Any reasons not to use Lift? Is Lift bad at anything?

167 views
Skip to first unread message

DoomPirate

unread,
Jun 30, 2011, 12:41:54 AM6/30/11
to lif...@googlegroups.com
I think everybody in here knows why Lift an awesome choice for a web framework. (fast, concise, jvm-based, flexible, scalable)
In my eyes, I truly do see Lift/Scala being way ahead of its time and revolutionary. 

I don't think Lift has too many pitfalls or negatives, but I still would like to know them.
I am interested in knowing if there are any "cracks" in Lift when developing super highly scalable/dynamic/interactive webapps similar to facebook, youtube,. 

The only negatives that I can think of is that Scala needs more adoption.

Thanks

  

TylerWeir

unread,
Jun 30, 2011, 8:47:13 AM6/30/11
to lif...@googlegroups.com
Difficulty in finding other devs in your area.

I'm in Toronto, and there are hardly any Scala/Lift nerds to hire.

That's all I know about.

Andy Czerwonka

unread,
Jun 30, 2011, 9:09:42 AM6/30/11
to lif...@googlegroups.com
Same here in Calgary.  I've started a Scala Enthusiasts Meetup to try and create some Java refugees.

Jeppe Nejsum Madsen

unread,
Jun 30, 2011, 10:21:42 AM6/30/11
to lif...@googlegroups.com
On Thu, Jun 30, 2011 at 3:56 PM, Byron Weber Becker
<bwbe...@uwaterloo.ca> wrote:

[...]

>  For example, trying to use
> a SessionVar before the session has been created shouldn't just refuse to be set.  It
> would be nice to have an exception reporting the problem.

I think your points are valid to a certain degree, but for this
specific problem there's a solution in LiftRules:

/**
* Should an exception be thrown on out of scope Session and RequestVar
* access. By default, no.
*/
@volatile var throwOnOutOfScopeVarAccess: Boolean = false

/Jeppe

Mark Nelson

unread,
Jun 30, 2011, 10:24:10 AM6/30/11
to lif...@googlegroups.com

If i could have something to make lift better it would like be a lot more widgets with a lot of ootb functionality.  Tables, charts, maps, trees, etc. That know how to sort, filter, hide/show, animate, scale, etc.

:-)

On Jun 30, 2011 11:57 PM, "Byron Weber Becker" <bwbe...@uwaterloo.ca> wrote:
> I'm still a newbie at Lift -- I've been working at it about half-time with a student
> (who is full-time). I have no experience with other frameworks; previous web-development
> has been in just plain python with python libraries.
>
> I've found the learning curve to be really steep. Part of this is because there is little
> formal documentation. The books (Exploring Lift, Simply Lift) are great but still incomplete.
> The wiki is often helpful, but often not. The ScalaDoc is barebones at best. The bright
> spot is the usually helpful on-line community. But the on-line community is going to get
> burned out. We, collectively, need to work on the formal documentation.
>
> Secondly, Scala allows lots of cool things like implicits and DSLs and passing around
> functions and partial functions. However, I'm not convinced that we've developed a best
> practise yet on when/where/how to use them and (there's a theme here) how to document them.
> In the relatively short time that I've been reading the Lift group, there have been too
> many (in my opinion) questions along the lines of "I'm reading the code for X but I don't
> understand how Y is happening". I believe there is a trade-off between the expressivity of
> Lift and the cost of learning that expressivity. I suppose this will change as I become
> more familiar with Lift, but at the moment I'd take less expressivity and a lower learning
> curve.
>
> Thirdly, I've been caught a couple of times -- and have observed others in the same
> situation -- with trying to do things at inappropriate times in the Lift Request/Response
> lifecycle. Lift uses Boxes a lot to avoid explicit failures. Sometimes, though, an
> explicit failure would be a wonderful aid to the programmer. For example, trying to use

> a SessionVar before the session has been created shouldn't just refuse to be set. It
> would be nice to have an exception reporting the problem.
>
> In spite of the above, I'm enjoying my foray with Scala and Lift, I believe that they are
> excellent tools, and the folks in the Lift community are wonderful!
>
> Byron

>
> On 2011-06-30, at 12:41 AM, DoomPirate wrote:
>
>> I think everybody in here knows why Lift an awesome choice for a web framework. (fast, concise, jvm-based, flexible, scalable)
>> In my eyes, I truly do see Lift/Scala being way ahead of its time and revolutionary..
>>
>> I don't think Lift has too many pitfalls or negatives, but I still would like to know them.
>> I am interested in knowing if there are any "cracks" in Lift when developing super highly scalable/dynamic/interactive webapps similar to facebook, youtube,.
>>
>> The only negatives that I can think of is that Scala needs more adoption.
>>
>> Thanks
>>
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups "Lift" group.
>> To view this discussion on the web visit https://groups.google.com/d/msg/liftweb/-/TBOBFzuzEjcJ.
>> To post to this group, send email to lif...@googlegroups.com.
>> To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
>> For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
>
> ---------------------------------------------------------
> Byron Weber Becker Voice: 519-888-4567 x34661
> School of Computer Science Fax: 519-885-1208
> University of Waterloo Office: DC3105
> Waterloo, ON N2L 3G1
>
> Advising FAQ: http://www.cs.uwaterloo.ca/current/faq/index.shtml
>
> --
> You received this message because you are subscribed to the Google Groups "Lift" group.
> To post to this group, send email to lif...@googlegroups.com.
> To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
>

Byron Weber Becker

unread,
Jun 30, 2011, 9:56:59 AM6/30/11
to lif...@googlegroups.com

Byron

> I think everybody in here knows why Lift an awesome choice for a web framework. (fast, concise, jvm-based, flexible, scalable)

> In my eyes, I truly do see Lift/Scala being way ahead of its time and revolutionary..

>
> I don't think Lift has too many pitfalls or negatives, but I still would like to know them.
> I am interested in knowing if there are any "cracks" in Lift when developing super highly scalable/dynamic/interactive webapps similar to facebook, youtube,.
>
> The only negatives that I can think of is that Scala needs more adoption.
>
> Thanks
>
>
>

Byron Weber Becker

unread,
Jun 30, 2011, 11:53:51 AM6/30/11
to lif...@googlegroups.com
(New subject; was in "Re: [Lift] Any reasons not to use Lift? Is Lift bad at anything?" thread.)

Thanks for the pointer, but I don't think it's working. After messing around with it
in my own project, I did the following:

1. downloaded the examples from https://github.com/lift/lift_23_sbt.git

2. Compiled and ran fine using sbt

3. Added

// Find out if we access SessionVars or RequestVars inappropriately.
LiftRules.throwOnOutOfScopeVarAccess = true

as the last line in Boot.boot

4. Ran again and it threw an exception:

[info] == jetty-run ==
[success] Successful.
[info]
[info] Total time: 2 s, completed Jun 30, 2011 11:48:02 AM
> 11:48:04.848 [1193485506@qtp-1743791445-0] ERROR net.liftweb.http.LiftRules$$anon$1 - Exception being returned to browser when processing /: Message: java.lang.IllegalAccessException: Access to SessionVar outside a request or comet actor scope
net.liftweb.http.SessionVar.findFunc(Vars.scala:71)
net.liftweb.util.AnyVarTrait$$anonfun$is$1.apply(AnyVar.scala:137)
net.liftweb.http.SessionVar.doSync(Vars.scala:125)
net.liftweb.util.AnyVarTrait$class.is(AnyVar.scala:136)
net.liftweb.util.AnyVar.is(AnyVar.scala:89)
net.liftweb.util.AnyVarTrait$class.get(AnyVar.scala:161)
net.liftweb.util.AnyVar.get(AnyVar.scala:89)
net.liftweb.util.StackableMaker$class.find(Maker.scala:150)
net.liftweb.http.Factory$FactoryMaker.find(Factory.scala:37)
net.liftweb.http.Factory$FactoryMaker$$anonfun$make$1.apply(Factory.scala:87)
net.liftweb.http.Factory$FactoryMaker$$anonfun$make$1.apply(Factory.scala:87)
net.liftweb.common.EmptyBox.or(Box.scala:563)
net.liftweb.http.Factory$FactoryMaker.make(Factory.scala:87)
net.liftweb.http.Factory$FactoryMaker.vend(Factory.scala:82)
net.liftweb.http.S$class.statelessInit(S.scala:1186)
net.liftweb.http.LiftServlet.doService(LiftServlet.scala:244)
net.liftweb.http.LiftServlet$$anonfun$doIt$1$1.apply(LiftServlet.scala:122)
net.liftweb.http.LiftServlet$$anonfun$doIt$1$1.apply(LiftServlet.scala:121)

(lots omitted)

David Pollak

unread,
Jun 30, 2011, 12:54:14 PM6/30/11
to lif...@googlegroups.com
Bryon,

Thanks for your list.  I was compiling a list last night and you've hit most of the points I had on my list.

A few more:
  • Lift is not opinionated enough about immutable data structures... this leads to much "Java-like" coding styles which is generally at odds with how Lift has envolved.
  • All the configuration in Boot.scala (even if it's calls out to other methods) is not optimal... have some more "declarative" or "by convention" configuration would be better.  This typically manifests itself in larger projects.
  • Lift apps are not modular enough... the Boot.scala issue is one place where this manifests itself, but also in the flat snippet resolution stuff (although the latter is being rectified).
  • Lift apps are not composable enough.  Snippets are great for allowing the composition of a page, but Screen, Wizard, Comet, and some other parts of Lift lead to monolithic structures.
  • Lift is ambivalent about how to treat JavaScript.  Sometimes Lift abstracts it away, sometimes Lift gives up and says JSRaw(....).
  • Lift is different than other web frameworks and the learning curve is quite nasty in some cases (the unlearning other paradigm cases.)
With that being said, I still think that Lift is worlds better than any other web framework I've used (yeah, I'm biased.)

Thanks,

David
Lift, the simply functional web framework http://liftweb.net

David Pollak

unread,
Jun 30, 2011, 1:55:42 PM6/30/11
to lif...@googlegroups.com
Please open a ticket (http://ticket.liftweb.net you must be a watcher of the LiftWeb space on Assembla), assign it to me and reference this thread.

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.

Naftoli Gugenheim

unread,
Jun 30, 2011, 6:46:26 PM6/30/11
to lif...@googlegroups.com
On Thu, Jun 30, 2011 at 12:54 PM, David Pollak <feeder.of...@gmail.com> wrote:
  • All the configuration in Boot.scala (even if it's calls out to other methods) is not optimal... have some more "declarative" or "by convention" configuration would be better.  This typically manifests itself in larger projects.
  • Lift apps are not modular enough... the Boot.scala issue is one place where this manifests itself, but also in the flat snippet resolution stuff (although the latter is being rectified).
  • Lift apps are not composable enough.  Snippets are great for allowing the composition of a page, but Screen, Wizard, Comet, and some other parts of Lift lead to monolithic structures.

Interested in illustrations of these playing out, and any thoughts on how things could have been done differently and/or can be improved.

David Pollak

unread,
Jun 30, 2011, 7:04:38 PM6/30/11
to lif...@googlegroups.com

Lift could slurp through the classpath and do stuff by convention... I personally despise that kind of solution as it means that if someone includes a JAR in the classpath that contains "stuff" that "stuff" will be part of the app.

In terms of composability... looking at WebSharper and some of the FRP stuff... I think there's a lot to learn (although you've clearly learned some of it with Reactive Web.)
 

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.

William Wilson

unread,
Jun 30, 2011, 9:53:15 PM6/30/11
to lif...@googlegroups.com
On Thu, Jun 30, 2011 at 10:54 AM, David Pollak <feeder.of...@gmail.com> wrote:
  • Lift is different than other web frameworks and the learning curve is quite nasty in some cases (the unlearning other paradigm cases.)
This is not a flaw, to make progress you must be different.  In fact this is why I chose Lift for my current project - wanting to avoid MVC, or at least MVC the way it is usually done.

I think the most dangerous Scala feature is overuse of implicit conversions, because of the negative effects on type checking.  Although they don't technically weaken the type system, in practice they do because type checking doesn't just mean that your function call can work on the data type you are passing.  Type checking also enforces that the type you were passing was actually the type you thought you were passing, which is equally if not more important.  I had an X, but the function wanted a Y, but since the compiler knew how to change an X into a Y it did without me necessarily meaning to do that.  (Anyone who has ever had Java code throw a NullPointerException on a line of code that appears to only handle primitives knows what I mean - autoboxing, which is really just a weak form of implicits, applies the conversion transparently, allowing you to forget you're actually dealing with an object reference).  In Scala you're less likely to stumble over a null, but you have a much wider variety of types that "almost but not quite" match.

Naftoli Gugenheim

unread,
Jun 30, 2011, 10:58:05 PM6/30/11
to lif...@googlegroups.com
On Thu, Jun 30, 2011 at 7:04 PM, David Pollak <feeder.of...@gmail.com> wrote:


On Thu, Jun 30, 2011 at 3:46 PM, Naftoli Gugenheim <nafto...@gmail.com> wrote:
On Thu, Jun 30, 2011 at 12:54 PM, David Pollak <feeder.of...@gmail.com> wrote:
  • All the configuration in Boot.scala (even if it's calls out to other methods) is not optimal... have some more "declarative" or "by convention" configuration would be better.  This typically manifests itself in larger projects.
  • Lift apps are not modular enough... the Boot.scala issue is one place where this manifests itself, but also in the flat snippet resolution stuff (although the latter is being rectified).
  • Lift apps are not composable enough.  Snippets are great for allowing the composition of a page, but Screen, Wizard, Comet, and some other parts of Lift lead to monolithic structures.

Interested in illustrations of these playing out, and any thoughts on how things could have been done differently and/or can be improved.

Lift could slurp through the classpath and do stuff by convention... I personally despise that kind of solution as it means that if someone includes a JAR in the classpath that contains "stuff" that "stuff" will be part of the app.

I don't have such a clear picture of the intention of "by convention" in this context. I was under the impression that frameworks that advertise "convention over configuration" mean, that rather than having to specify every setting, defaults are assumed, and whenever the framework's assumptions aren't what you want, only then do you have to specify them manually. For instance, rather than an ORM requiring annotations on every property indicating how to serialize it, the ORM can figure things out based on its name and type, etc. But in the case of Lift, I think it is already that way --- for instance, all the LiftRules members are set to defaults that are presumed the common usage.
 

In terms of composability... looking at WebSharper and some of the FRP stuff... I think there's a lot to learn (although you've clearly learned some of it with Reactive Web.)

Looking at http://www.websharper.com/docs/WorkingWithFormlets.aspx, it doesn't seem like formlets are about any kind of rocket science (or scalaz hierogyphics). I haven't used Screen or Wizard really, so I can't talk much, but it seems like it wouldn't be a huge change to make Screen and Wizard support what capabilities formlets bring to the table.

Since we're on the topic, I may as well give expression to what bothers me about a few things in Lift. It seems that some things have a more closed kind of design, like fixed ADTs, rather than a more extensible approach typical in OOP*. My assumption was that they were done this way for optimization purposes, though I wouldn't know if it was just due to assumed usage. An illustration could be LocParams and QueryParams --- there's no way to define your own, because the logic is not in the *Param, it's in one central place that pattern matches over them. Like I said, I haven't used Screen or Wizard so I don't know, so I don't know if this applies to them.
Not necessarily that big of a deal, just figured I might as well mention it in this thread...

* I don't mean OOP as opposed to FP. The reference is to a discussion in one of the Scala resources about pattern matching, which compares the pros and cons of a closed ADT vs. an open class hierarchy. With ADTs the set of types is pretty much fixed, but it's easy to add new operations over the set, as opposed to regular class hierarchies, where it's easy to add new implementations, but because it's an open set, it's hard to add new operations later.

Jeppe Nejsum Madsen

unread,
Jul 1, 2011, 3:53:54 AM7/1/11
to lif...@googlegroups.com
Naftoli Gugenheim <nafto...@gmail.com> writes:


[...]

>> In terms of composability... looking at WebSharper and some of the FRP
>> stuff... I think there's a lot to learn (although you've clearly learned
>> some of it with Reactive Web.)
>>
>
> Looking at http://www.websharper.com/docs/WorkingWithFormlets.aspx, it
> doesn't seem like formlets are about any kind of rocket science (or scalaz
> hierogyphics). I haven't used Screen or Wizard really, so I can't talk much,
> but it seems like it wouldn't be a huge change to make Screen and Wizard
> support what capabilities formlets bring to the table.

I think the Websharper formlets are rather deep. I saw a presentation at
the London Functional Exchange which was rather impressive wrt
composability. A complex form for editing values of type T was easily
composed (without changing the original form) into a form for editing
values of type List[T], complete with Ajax add/delete item, validations
etc.

This could of course be done in Lift as well, but I think? it requires
som redesign of the basic ways of generating forms.

/Jeppe

David Pollak

unread,
Jul 1, 2011, 1:09:25 PM7/1/11
to lif...@googlegroups.com
On Thu, Jun 30, 2011 at 7:58 PM, Naftoli Gugenheim <nafto...@gmail.com> wrote:


On Thu, Jun 30, 2011 at 7:04 PM, David Pollak <feeder.of...@gmail.com> wrote:


On Thu, Jun 30, 2011 at 3:46 PM, Naftoli Gugenheim <nafto...@gmail.com> wrote:
On Thu, Jun 30, 2011 at 12:54 PM, David Pollak <feeder.of...@gmail.com> wrote:
  • All the configuration in Boot.scala (even if it's calls out to other methods) is not optimal... have some more "declarative" or "by convention" configuration would be better.  This typically manifests itself in larger projects.
  • Lift apps are not modular enough... the Boot.scala issue is one place where this manifests itself, but also in the flat snippet resolution stuff (although the latter is being rectified).
  • Lift apps are not composable enough.  Snippets are great for allowing the composition of a page, but Screen, Wizard, Comet, and some other parts of Lift lead to monolithic structures.

Interested in illustrations of these playing out, and any thoughts on how things could have been done differently and/or can be improved.

Lift could slurp through the classpath and do stuff by convention... I personally despise that kind of solution as it means that if someone includes a JAR in the classpath that contains "stuff" that "stuff" will be part of the app.

I don't have such a clear picture of the intention of "by convention" in this context. I was under the impression that frameworks that advertise "convention over configuration" mean, that rather than having to specify every setting, defaults are assumed, and whenever the framework's assumptions aren't what you want, only then do you have to specify them manually. For instance, rather than an ORM requiring annotations on every property indicating how to serialize it, the ORM can figure things out based on its name and type, etc. But in the case of Lift, I think it is already that way --- for instance, all the LiftRules members are set to defaults that are presumed the common usage.
 

In terms of composability... looking at WebSharper and some of the FRP stuff... I think there's a lot to learn (although you've clearly learned some of it with Reactive Web.)

Looking at http://www.websharper.com/docs/WorkingWithFormlets.aspx, it doesn't seem like formlets are about any kind of rocket science (or scalaz hierogyphics). I haven't used Screen or Wizard really, so I can't talk much, but it seems like it wouldn't be a huge change to make Screen and Wizard support what capabilities formlets bring to the table.

Since we're on the topic, I may as well give expression to what bothers me about a few things in Lift. It seems that some things have a more closed kind of design, like fixed ADTs, rather than a more extensible approach typical in OOP*. My assumption was that they were done this way for optimization purposes, though I wouldn't know if it was just due to assumed usage. An illustration could be LocParams

You can create subclasses of Loc.LocParam.  In this way, you can add attributes or other decorators to your Loc's.  The fact that Lift's built in features won't make use of those would not prevent you from implementing your owns snippets that look for your own custom LocParams.
 
and QueryParams --- there's no way to define your own, because the logic is not in the *Param, it's in one central place that pattern matches over them. Like I said, I haven't used Screen or Wizard so I don't know, so I don't know if this applies to them.
Not necessarily that big of a deal, just figured I might as well mention it in this thread...

QueryParams are much more difficult.  The phases of query building are so twisted (partially because Mapper was my first Scala code and I was more focused on learning the language and getting "something" done fast and partially because query building is inherently nasty) that it would take a lot of pre-planning to get all of the "cut points" both right and then allow modification of the SQL AST by anything at any point in the query building process, plus you'd have to have a mechnism for ordering the AST building/rewriting.  While it might be possible, an ORM has never been Lift's focus and getting it "more right" than Squeryl is more work than I'm willing to undertake, although you are encouraged to take on the task much like Peter is taking on the JavaScript DSL work.

With all that being said, thank you for your comments.  They are valuable.  Please read my responses as a history (skills, efforts, timeline) rather than a rejection of your comments.
 

David Pollak

unread,
Jul 1, 2011, 1:17:39 PM7/1/11
to lif...@googlegroups.com

Also, WebSharper and a number of the Haskell-derived libraries inspect intermediate code and generate JavaScript based on the analysis of intermediate code.  Short of having a Scala compiler plugin or going the GWT route, it'd be pretty hard to get all of WebSharper's functionality in Lift.
 

/Jeppe

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.

David Pollak

unread,
Jul 1, 2011, 12:59:19 PM7/1/11
to lif...@googlegroups.com
On Thu, Jun 30, 2011 at 6:53 PM, William Wilson <fluff...@gmail.com> wrote:
On Thu, Jun 30, 2011 at 10:54 AM, David Pollak <feeder.of...@gmail.com> wrote:
  • Lift is different than other web frameworks and the learning curve is quite nasty in some cases (the unlearning other paradigm cases.)
This is not a flaw, to make progress you must be different.  In fact this is why I chose Lift for my current project - wanting to avoid MVC, or at least MVC the way it is usually done.

I think the most dangerous Scala feature is overuse of implicit conversions, because of the negative effects on type checking.

I couldn't disagree with you more.  In Java, a nominally statically typed language, there are casts all over the place and very often in many Java programs, the type requirements are so complex that developers pass around String and then convert String -> XML or JSON or something else inside the target method.  Implicits are a normalization of the conventions that arise in Java programs.

The challenge with implicits is that they are not obvious in the source code at the call-site.  But exchanging the ability for the compiler to insure that the type can actually be converted from A => B or that there is actually a helper that can build the appropriate collection is a vast improvement over the realities of Java code.
 
  Although they don't technically weaken the type system, in practice they do because type checking doesn't just mean that your function call can work on the data type you are passing.  Type checking also enforces that the type you were passing was actually the type you thought you were passing, which is equally if not more important.  I had an X, but the function wanted a Y, but since the compiler knew how to change an X into a Y it did without me necessarily meaning to do that.  (Anyone who has ever had Java code throw a NullPointerException on a line of code that appears to only handle primitives knows what I mean - autoboxing, which is really just a weak form of implicits, applies the conversion transparently, allowing you to forget you're actually dealing with an object reference).  In Scala you're less likely to stumble over a null, but you have a much wider variety of types that "almost but not quite" match.

Sure, implicits can be over-used, but doing background processing on the Java APIs for Lift, I think we've gotten the balance right in code that's gone into the codebase over the last 3 years.

As with any sharp tool, the tool can cause pain, but having to choose between implicits which are explicit to the compiler and "conventions" which are only explicit to the team that understands them, I'd choose the former.
 

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
Reply all
Reply to author
Forward
0 new messages