Hacker News new | past | comments | ask | show | jobs | submit login
Light Table 0.4 released (chris-granger.com)
544 points by cf on April 30, 2013 | hide | past | favorite | 189 comments



Aside: The 3d js demo (http://threejs.org/examples/webgl_buffergeometry.html) is close to a worst-case input for a video encoder, which is why the youtube video looks so bad.

Video codecs generally encode motion first ("move this rectangle left 10 pixels"), and then fix any residual errors ("apply this patch"). It is _far_ more efficient to transmit motions and residuals than an entire frame.

This demo actively resists motion encoding, since a 3d volume shifting perspective is approximated poorly by a linear shift. Almost every pixel is changing each frame, in an unpredictable manner. Youtube doesn't allow the encoder enough bits to represent the actual image well, and the result is a blurry mess with occasional flashes of clarity when the encoder transmits a keyframe (an entire picture, added to allow fast seeking).


This editor has reached parity with Sublime Text in my workflow for these reasons:

1.) Vim bindings (less impressive accomplishment but necessary for me); 2.) fuzzy matching for files, commands, and settings (this concept really wins); 3.) having a browser as a tab(!, it makes working full screen a joy); 4.) object eval(!); 5.) and EXCELLENT autocomplete -- even in Coffeescript -- most likely a product of the eval stuff going on, but better than Sublime. Wow. GREAT WORK.

My wishlist of generic "power user" features: macros support (for ex., I'd like to set Cmd-Del to delete up one line), configurable margins, more preloaded skins, a way to easily change the color palette of a skin, and tmux / real-time collaboration equivalent.

I have gotten around certain quirks ~ add a tabset to simulate margins, also add a key binding for adding a tabset to mock the vsplit vim command

After the Nifty Minidrive failure and others, I can surely say this is the best money I've spent on Kickstarter.


Can you elaborate a little on how Coffeescript works in your setup? I was thinking of trying 0.4 out but I wasn't sure how exactly that language (which I use daily) might fit in.


It was plug-and-play! :D Here's a screenshot of it just working: http://www.fixpunk.com/notes/?attachment_id=78 My setup is nothing elaborate: I have set watch commands on my coffee directories and work with a node server running.


Awesome! I'm trying to visualize how some of the features from the Javascript video in OPs post (http://www.youtube.com/watch?v=gtXpOD6jFls) would work. Are you using it as a straight editor or are you able to take advantage of the killer LightTable features in conjunction with Coffeescript (perhaps the new source-maps stuff takes care of it)?


Yeah, I haven't seen the realtime eval work in Coffeescript - I have to save the file and refresh the browser. That said--the awareness of the workspace environment really blew me away and pays off in tab completion.


It's nearly there for me, only a couple of things holding me back at the moment:

* Fuzzy matching doesn't intelligently handle spaces in the search string whereas ST does (very handy for deep directory structure). * No indentation detection or quick switching / conversion between indentation schemes.

I love the work Chris and the team are doing on LT at the moment, it's looking amazing at the moment, and am feverishly awaiting the source release so some of us can chip in and help!


Only thing it's missing for me is multiple cursors.


For those of us still stuck in the Dark Ages, I have patched Light Table so it can run on OS X 10.6.8 (Snow Leopard). You can download it here: https://s3-us-west-1.amazonaws.com/lighttable/LightTable0.4....


Thanks Zach, much appreciated.


No problem. :)


Greatly appreciated! Would love to see how this was done incase there's a need to patch future versions.



Thank you! That sure beats running it over ssh from my linux host.


Awesome thanks! Any features that don't work?


From what I can tell, everything's working as normal. Let me know if anything breaks though.


Awesome thanks, any chance you could push this to GitHub?


I don't actually have access to the Light Table source code. I'm actually just replacing the node-webkit libraries in Chris's release with ones compiled on Snow Leopard, so I don't think there would be much of an advantage to having it on GitHub.


This is a huge release - so many awesome new features. The Python integration alone has been one of the things I've been waiting for to really dive into Light Table and give it a spin for longer than 10 minutes.

Congrats to the Light Table team!


This looks really awesome; looks like Hotswap for the JVM.

I wonder how they handle updating anonymous function references--in the JVM, everything ends up being a class name (e.g. Foo$1 whatever), so even "anonymous" classes technically have an identifier to say "here's the new code". I wonder what that is for Light Table/the V8 VM.

I'd love to see this hotswap behavior built into all JS wire/debugger protocols. Maybe a W3C spec?

Light table is really awesome, and really driving the bleeding edge, but debugging/inspecting/hotswapping seems like something other editors could do as well.


I really want to improve/make new syntax languages for this and actually use it.

Problem is that CodeMirror's docs for it are a tad confusing and I'm not even sure if it will be as flexable as Sublime/textmate .tmLanguage syntaxing. Anyone got a good resource or advice on this?

For example, I want to highlight function calls in coffeescript, such as:

   obj.func '100', () ->
Where "func" is highlighted differently. I've accomplished this with a .tmLanguage with relative strife, so I am wondering how easy it will be to do things like this with CodeMirror.

Once this thing goes open source I'd be happy to revamp all of the syntax highlighting for js/cs/css/stylus/html etc. should this make any sense, though technically as it uses CodeMirror I'd be revamping for them instead. Of course this would mean editing the .css files provided by LightTable though, so I'm half right.


> Problem is that CodeMirror's docs for it are a tad confusing and I'm not even sure if it will be as flexable as Sublime/textmate .tmLanguage syntaxing. Anyone got a good resource or advice on this?

They are more flexible, but a bit harder to get going with. Basically, you get to implement a full parser, if you want, or just a tokenizer (optionally keeping some minimal state).


Very cool! Its great to see this progressing at such a fast rate, and I'm glad I got the chance to be a part of the Kickstarter. Are there any plans for Ruby support? I know Python was first as it was the stretch goal, but Ruby has been mentioned in passing a couple of times.


This is an impressive release. They move forwards at an amazing pace. I had already been using LT 0.3.9 almost exclusively for my ongoing Clojure projects during the last month, switching back to Emacs only for heavy editing tasks.

I was really missing but the ability to (de-/re-)connect to a given client, which 0.4.0 provides. In my opinion LT is not just a code editor (editing features are pretty poor yet indeed) but a code experimenting platform. And there it rocks. Even in alpha, it compares pretty well with Emacs Live in terms of stability and usability.

ClojureScript, Node and JS support is a terrific move. This means I may even soon use Brackets (another nice node-webkit project) less for live JS HTML coding and debugging and live mostly in LT.

Congratulations Chris and Co!


I would say, rather, that it is not a mature code editor. It aims in all seriousness to do anything we expect a code editor to do, and I have every reason to think the project will succeed.

Chris is focusing on providing new functionality; the expected stuff can and should come later.


This is my understanding too. (This is why I said yet).

I am expecting a lot from the forthcoming plugin system. It will be nice to be able to script LT in ClojureScript (the language in which LT is mostly developed).


It looks pretty nifty! It's kind of like what Subtext and Bicicleta wanted to do, but never did (or haven't done yet). You get live update of the code and, apparently, live inspection of all the values in the code. The missing piece would be inspecting values inside a function call.

But it sounds like it's proprietary software? Why do you need that if you're getting funded through Kickstarter?

Either way, it looks like a really inspiring project, and I hope we see many more like it.


What happened with Bicicleta? I love the premises I saw listed in response to Perlis.

LT will be open source, just want it to get a bit more stable first.


Oh, I've been pretty distracted with other (probably less important) things these, uh, years. embarrassed face

My first prototype implementation, a tree-walking interpreter in OCaml I threw together in a few days, was discouragingly slow, so a lot of work may be needed to get it to run acceptably fast; and I haven't done the GUI work to realize the potential Light-Table-land advantages yet.


> LT will be open source, ...

The licensing situation is really unclear. The Kickstarter page says, "In order to download packaged distributions, you'll need a license". But I expect that, if it's open source, I can get a packaged distribution by saying (I'm using Arch Linux):

    # pacman -S lighttable


Maybe he's figured out by now that most people now know better than to tie their programming career to a proprietary editor. The Kickstarter was about a year ago. (Still, how is he going to deliver on his "50 licenses" rewards if he makes it open source? At this point, he's put himself in a position where he has to break his promise to somebody.)


It will be open source? Can't wait to use it then.


Holy shit, basically. I mostly do Python and JS, so this means that now Light Table is pretty much THE editor for me. Huge update.

I can only hope for eventual PHP integration so it's useful to me also at work.


Now that source maps are in CoffeeScript, any chance of future support? Also, vim bindings?


There are vim bindings. From the docs:

  Use the "Vim: Toggle vim mode" command from the command tab.


I wonder if will it be possible to associate user defined clojurescript commands with arbitrary vim keybindings? That would be great! Also, I wonder if there will be support for user defined vim like operators and motions... Or, alternatively, if the plugin architecture will be low level enough to support a vim "emulation" plugin.

Also -- very, very exciting work overall -- visionary even. Kudos!


I wonder how useful these are. It seems like a lot of the functionality of Light Table is accessed through mouse interactions.

With that said, I could still use some emacs bindings :)


Doesn't work with Ubuntu 13.04 :/ Binary is linked to libudev.0 but Ubuntu now uses libudev.1

Any chance me, as a non-tester and interested person, gets a "fix" for that?

edit: linking 1 to 0 works so far, but please consider a migration to new version - e.g. chrome did the same some time ago ago[0].

[0] https://groups.google.com/a/chromium.org/forum/?fromgroups=#...


Someone below mentioned the same thing, with a response from Chris: https://news.ycombinator.com/item?id=5633069


Thanks !


Been waiting for Python support since I first heard of the project! Getting an error trying to connect to Python 3 process, works with Python 2.7 though. According to OP's post Python 3 should be compatible, but I get this error:

Looks like there was an issue trying to connect to the project. Here's what we got:

    Traceback (most recent call last):
  File "C:\Users\way\.lighttable\plugins\python\ltmain.py", line 12, in <module>
    import ltipy
  File "C:\Users\way\.lighttable\plugins\python\ltipy.py", line 181
    print "no proc"
                  ^
SyntaxError: invalid syntax

which looks like a typical error when running 2.7 code on 3+. Anyone else suffering from the same issue or is something messed up on my end? Running Windows 64-bit, Python 3.3, IPython 0.13.


I dream of the day Light Table has Go support.


You know, I looked into this briefly and based on the way go works, it's not clear to me how useful it would be. Go doesn't really have a good REPL, which is an indication.

If there was a decent way to handle dynamic evaluation though, it could certainly be added, and without too much issue I would imagine :)


Go compiles so fast you can just pretend there is dynamic eval. People sometimes use the "go run" command to compile and run Go source in one operation, that is not really too different from just invoking an interpreter. Go provides a lot of tools to parse Go source, I imagine between that, Go's fast compiler and GDB support it wouldn't be as hard as many compiled langs to support.

Also if I am figuring out something OBO (off by one) prone sometimes I use this to double check myself: http://play.golang.org/


>Go compiles so fast you can just pretend there is dynamic eval.

Yes, the Go people keep mentioning that. You might as well eat soy and pretend it's a delicious steak.

For people that have used good REPLs, from Lisp machines to iPython, it's not the same thing at all.

You lose your state, you loose context, you loose good introspection, etc etc. And if you try loading stuff that's big (several packages as dependencies etc), the compile time starts adding up too.


The big difference is that you lose state every time you do that, the main goal with the eval in LT is to prevent that :)


If there is a way to consistently inject the input to the program (to lead to the same state), I would be OK with editing a Go program to cause (behind the scenes):

  1. moving a break point 
  2. recompile
  3. run
  4. stopping at new break point
I think that happening behind the scenes could be made to appear like live editing in other languages. Go is fast enough compiling and fast enough executing that I think it could be pulled off as not appear laggy as well. But maybe I'm wrong and I don't understand well enough how LT handles other langs.


Have you ever used a REPL?

It is an interactive process. You are build pieces of the application bit by bit.

There is no complete application state where to set breakpoints.



But compiling + running means that every time you have absolutely fresh process without old state, so it's pretty different from what you can do with JS or Python.


Why would a REPL be necessary? They don't handle the problem of inspecting a call in context anyways; e.g. it seems like you are hooking directly into the vm for JavaScript to do live inspection. Fix and continue might be sufficient.


It would be a different direction than what you've done so far, but I'd love to see what you could do for statically typed languages. I'm thinking less about repls and evaluation and more about supercharged autocomplete and refactoring tools.

I know this is already done in any number of big enterprisey IDEs, but you would surely take a fresh and creative approach.

Go would be a perfect test candidate.


There is no reason static languages can't support REPLs and evaluation. All of my live orgiramming work so far has involved rich static typing, though I admit more implicit typing would make the experience better....


I wrote about this recently in post about future startup ideas [1]. Go is young and building an IDE along with its evolution would be amazing. LightTable might be very successful with that, but I imagine the more exciting place for Go IDE experiments could be Android and tablets. As multicore mobile takes over, I think a few years out apps in Go might be a popular thing; and building software on the target platform hasn't happened much with mobile yet. AIDE [2] is really really amazing, but it's not quite the revolution that I'm looking for. I'm quite excited for where this goes.

[1]: http://www.jacobsheehy.com/2013/03/living-in-the-future-star...

[2]: https://play.google.com/store/apps/details?id=com.aide.ui


This is awesome, congrats on the release.

I'm very excited with the Python integration. I'm going to try doing some web development with Light Table now. One thing that would be very handy would be support for virtualenvs or requirements files to integrate into workspaces so that we can work on projects without installing all dependancies globally.


Yeah, virtualenvs support is an absolute must have for it to be considered seriously for Python development.


If you run LT from the command line after you've activated your venv it will use it.

  $ workon foo
  $ /PATH_TO_LT/LightTable.app/Contents/MacOS/node-webkit


That worked. Thanks!


I am very excited to play with Python eval on Light Table. I am on Windows. Python PATH is not set. So I had set it in Command-line. cmd was able to execute Python, but light-table is not able to detect Python PATH. How can I set Python PATH in Light Table on Windows?


You can set the environment variables in windows 7 by right clicking Computer then click on properties > Advances system settings (on the left), and then click on Environment Variables. Scroll down in the System Variables box, and edit Path. Add ;C:\<path to python> at the very end.


I had done that. Probably I have to restart the system to have Light Table understand the updated PATH.


I only had to restart Light Table after adding the path to python in the path envvar.


Logout/login is enough.


It would be great to get a common lisp supported in Light Table...


People still use common lisp? ducks

In all seriousness, the plugin architecture will certainly allow for exactly that to happen. If you're interested in trying your hand at adding CL, I know a guy who could probably sneak you into the beta when it turns private ;)


I stopped serious use of common lisp about 5 years ago - but jokes about lisp not seeing serious use still hurt. :)


I was actually suggesting that I can't believe people still use CL when Clojure exists...

I await my lynching. :D


Well, since you threw that out there...

...I can't believe that people use Clojure-the-language over CL-the-language. It seems to have no reason to exist except as a "I hate parens" Lisp-1. The interesting parts of Clojure (i.e., the sequence abstraction design) are replicatable in CL as a library. Extant issues (e.g., cl's map not mapping over vectors)* can be abstracted over with other tools.

While the JVM interop is compelling, I don't understand why the libraries and macros to create similarly compelling interop over ABCL weren't developed instead.

Bluntly, I don't know why Clojure was created as a new language instead of an advanced library over Common Lisp. I appreciate the interest it's been able to drum up in the Lisp family, and I deeply appreciate the libraries people have written for it.

*: I was wrong: map goes over a variety of types: mapcar, mapcan, etc, are common and only operate on lists. Ignorance uncovered and filled in by knowledge.


>The interesting parts of Clojure (i.e., the sequence abstraction design) are replicatable in CL as a library.

The interesting part of Clojure for me is that the sequence abstraction design is part of the standard language distribution and NOT implemented as an optional library.

The major flaw with Lisps is exactly the proliferation of competing, (and frequently half-arsed), custom solutions for stuff that should be built-in and used by all.

I'll take a slightly inferior implementation of something that's standard in a language's libs, over 20 competing solutions or rolling my own, any day of the week.


The only reason I can understand for the existence and use of Clojure is interoperation with Java and because Clojure is more actively developed than ABCL.

The big question to me is why people who do not need Java interop are using Clojure. Here are some reasons I can think of:

- The tooling around Clojure feels more familiar to Ruby/Python/Node programmers.

- Ruby/Python programmers need their programs to run slowly so that they can be certain something is happening.

- Cult of personality. Rich Hickey has a lot of great videos and conference presentations. Lisp has no apparent technical or thought leader. Followers need leaders.

- Hubris. The same stupidity that causes organizations to throw out Robert's Rules of Order and then subsequently reinvent non-standard solutions to the problems RR was created to solve in the first place.

P.S. CL's map works with all sequences, including vectors.


To be fair, unlike Ruby/Python/JS, Clojure actually tries to solve a relevant problem in a new way (concurrency). It is something that probably could have been built on top of Common Lisp, but at the same time, there is something to be said for having a relevant paradigm baked into the standard library from the beginning.


Nice way to ignore the big one.

It's less than one fifth of the age of CL, yet it has vastly superior libraries. Part of this is the Java interop, but at this point, even Clojure native libraries tend to be just better than CL libraries.

The reason for this is probably the common focus on good, sensible defaults and less on "everyone can easily roll their own". Having a set of basic, sensible data structures and abstractions that everyone share is not the same thing as "well, it's easy for anyone to do this". The idea that CL is flawless because it's so powerful that all flaws can be fixed by users is a disease, not a strength. It leads to a community where work is massively duplicated because all libraries are designed for a specific use, and every user needs to bend them to his uses.


You're making the same argument for why MIT started teaching Python instead of Scheme. I feel sorry for anyone whose life as a programmer is library spelunking instead of solving new problems.

If you think libraries are more important than having a truly interactive development environment that is Lisp 100% of the way down, you are missing out hugely on power and expressiveness. It has to be experienced to be understood. You're only fooling yourself and other people by thinking that Clojure is a "good enough" Lisp.


> I feel sorry for anyone whose life as a programmer is library spelunking instead of solving new problems.

You do realize that the vast majority of all the things that need to be done are essentially "library spelunking"? Not every programmer can spend his time doing AI research. A lot of the things that need to be done are "easy" but very work-intensive, and can be made much, much faster by good libraries. The majority of programming jobs are still essentially crud apps with a db backend, and CL is simply just a bad language to implement those in.

> If you think libraries are more important than having a truly interactive development environment that is Lisp 100% of the way down, you are missing out hugely on power and expressiveness. It has to be experienced to be understood.

I have experienced it, and understood it. And after 6 years of it, I switched to Java, because that's actually a more productive language to get things done in. Because even if the language itself is shit, things like internationalization and input validation have good libraries so I don't have to spend weeks working on getting all the little details right. Clojure buys me that, and a better language.

Clojure may not be a good enough lisp, but it's certainly better than CL.


Apologies to CL. I usually use MAP(CAR|CAN). I hadn't investigated MAP itself due to the extra parameter.


You're dangerously close to trolling, but I'll comment anyway.

> a "I hate parens" Lisp-1

Clojure's minimal syntax is, in my opinion, a gigantic improvement over Common Lisp. And I say this as a person who quite likes parens. I feel similarly about Lisp-1s, but that is well trotted territory: Lisp-1s have won.

Parens are overloaded in traditional Lisps for both invocation and grouping. The introduction of vectors with square brackets makes a lot of code a great deal more readable at virtually zero cost: It's still homoiconic. Similarly, the inclusion of curly braces for maps is wonderful, as it makes maps a lot more common in Clojure than they would otherwise be in CL, which is a good thing for most business logic.

> replicatable in CL as a library

Defaults matter. A lot. Presence in a library is insufficient. The fact that seqs et al are in core means that 100% of Clojure libraries use those abstractions. That's a big deal.

> I don't understand why the libraries and macros to create similarly compelling interop over ABCL weren't developed instead

Rich discussed this on the CL mailing lists long before Clojure or even his first attempt, dotLisp, ever existed. See [1] and [2]. In short, interop needs to be planned for at the lowest levels to make it pleasant to use and efficient to execute. And it's not just JVM interop: Clojure was designed for $SOME_HOST interop, so ClojureScript interops as nicely with JavaScript as Clojure does with the JVM. CL would have two different libraries with two different ideas of interop for two different host platforms.

> I don't know why Clojure was created as a new language

I think you have a different definition of the word "language" than I do. Look at PG's Arc. It's built on a scheme implementation. It's not so much a new language by your definition as it is a set of scheme libraries. But that's what a language is: A common base vocabulary encoded with a well known set of syntax and semantics rules. Clojure could be implemented (quite trivially, thanks to the aforementioned careful hosting design) as a set of libraries to CL, but it would still be a new language.

[1] https://groups.google.com/d/msg/comp.lang.lisp/3-X76dTw8dI/I... [2] https://groups.google.com/d/msg/comp.lang.lisp/3-X76dTw8dI/s...

Snippet from [2]:

    If one were starting from scratch,
    and supplied a platform like .NET, would one define Lisp the way CL is
    defined?

    I would hope the answer is 'most definitely not'. For instance, .NET
    provides for numbers, characters, strings, arrays, hashtables, exceptions,
    namespaces, files, streams, user-defined types, a type hierarchy and
    inheritance, I/O, object creation and initialization, reflection etc. Should
    a language define its own incompatible versions of these things in such an
    environment?


"Parens are overloaded in traditional Lisps for both invocation and grouping."

And boy do I wish they were overloaded the same way in Clojure. I hate the fact that I have to say

     (cond
       (some-long-predicate involving multipler-parameters)
       (what-to-do has to go-on-the-next-line because-of wrapping)
       (here-is-the-next predicate)
       [(func1 arg1) ...])
It's very easy to end up in this situation (and it's not always just a sign that you need to refactor). It messes things up visually, and it also means that #_ doesn't work to comment out an entire test-and-expression (likewise #_ doesn't comment an entire binding-plus-binding-expression in a let), because it's not just one s-expression.

I don't really understand the rationale, tbh (in fact I don't even know what it's supposed to be to try to understand it); somewhere I saw the observation that there's no need for you as a macro writer to make the client of the macro use parens for grouping when you can just call (partition 2 ...) on the arguments, which is true enough (at least, as long as the unpaired args in a larger group (e.g. binding vector) or are the tail of the arguments to the macro, captured as a rest param), but ... I kind of doubt that CL and Scheme went with the form of let, cond, etc. that they did out of convenience for implementation of the relevant macros. And even if that were the original motivation, those forms have other benefits.


I'm not sure how your cond example is related to vector syntax. The decision to use (partition 2 ...) style pairs, rather than extra brackets is orthogonal.

The more important point of literal syntax for composites other than lists is the fact that they are resolved at read time. This means you don't need a macro to have grouping. With (some-macro ((f x) (g y))), you need to force expansion inside the parens. Quoting (some-function '((f x) (g x))) requires forcing evaluation in your function. You could use (vector (f x) (g x)), but now that means some-function gets a vector argument and some-macro would get a list argument with first element 'vector. In Clojure, (some-function-or-macro [(f x) (g y)]) both have a vector as an argument because of the read-time behavior of data structure literals. Huge win in my book.


The cond example isn't related to vector-style syntax. There are two options: either the unpaired elements are the last (so you can get them from rest parameters) or the unpaired elements are already grouped somehow (for instance, by being in a vector). Cond does the former, let does the latter. I'm not sure why you're mentioning vector syntax at all since the comment you're replying to was specifically talking only about grouping.

Literal syntax for composites other than lists is totally unrelated to this.

I actually really don't understand why if you had (some-macro ((f x) (g y))) you'd have to "force expansion inside the parens", since well-behaved macros won't expand their arguments. You'd iterate through the elements in the parens, but ... that's what you'd do with clojure-style partition macros, too, you'd just call partition first.

For a function call the obvious choice, and one you see in Scheme/Racket quite frequently, is either `(,(f x) ,(g y)) for your second example, or even (list (f x) (g y)). Yeah, then your macro gets a list whose first element is 'list, but ... so what? Your macro probably shouldn't be looking inside what it receives anyway, and if it does then it should be documented that it expects a literal ((foo bar) (baz quux)) or whatever (just as in Clojure you can't write (let (vector 'a 'b) (+ a b)) and have that work).


Actually, I'd appreciate expansion on the respect in which Clojure is designed for interop with an arbitrary host. One (relatively uninteresting) respect in which that might be the case is that Clojure-the-language might not say anything about, say, what numeric types there are. Actually it does, though: Clojure supports ... all Java numeric types. And then there are two more Clojure-specific types. Or perhaps that is the sense in which it's designed for interoperation: it just says "we'll use the number types the host has".

Isn't it the case that Clojure and ClojureScript have different libraries with "different ideas" (whatever that means) about interop with their hosts? And ClojurePy yet other ideas about interoperation with Python? The hosts are very different in each case; how could the interoperation not be? (I suppose you could supply the host with a runtime that emulates aspects of the interoperation on the original host---but that's not very interesting!)

(Also, he mentions dotLisp in the post you reference as footnote [1].)


I disagree that Numbers are relatively uninteresting. In fact, I think any language designer would tell you that numerics are one of the hardest areas to get right. It's also the area where Clojure is weakest in terms of interop, I'd say. ClojureScript, for example, only has host Numbers (ie double-precision floating-point)

The main thing that Clojure does in terms of being designed for interop is to require the use of host values/objects. There are no wrapper/proxy/delegate/whatever objects. This has big implications. It (unfortunately) means that there is behavior you simply can't have in core, such as reflection or continuations. That's a big part of being interop friendly: Intentionally specifying fewer things. If you have very strict rules for how something like strings behave, then you might wind up in a situation where you need to create a ClojureString class or something like that.

Additionally, the '. (dot) special form is like a giant "INTEROP HERE" sign, which is extremely useful when porting code from CLJ to CLJS. You can literally grep your source for /\./ and find platform specific code.


What I meant is that "if designed for interop" in the case of numbers is something like "there is no design for numbers, just use the host's numbers", that's not a very interesting design. And it leads to, for instance, huge differences between Clojure and ClojureScript (as you note).


Minimal syntax can be implemented in reader macros in Common Lisp. If you really think some punctuation marks are more readable than a LAMBDA form you can write a reader macro to do it (and people have).

Parens are not overloaded in Common Lisp. It's always (function value value ...). And lists are always (). It's an artifact of homoiconicity that the program code can be represented in the same first-class data structures that it manipulates. I think we can all agree that is an advantage.

   '()
Is just a reader macro for QUOTE which returns its arguments unevaluated. LIST simply returns a new list from its arguments. BACKQUOTE lets you optionally evaluate parts of a list (which is useful unsurprisingly in macro definitions).

Re: seq; I don't really see the advantage. Some defaults might be right for certain applications but I prefer to be in control of making that decision.

ABCL interop is working rather well. They even have CLOS support now.

Parenscript generates great Javascript from Common Lisp code. The great thing about Lisp-like languages is that the evaluator can take a description of a process and create a machine capable of emulating that process. This happens to be really useful when experimenting with new languages. There's even a cl-python project to evaluate Python code in Common Lisp.

The great idea of Common Lisp was to bring together under one standard the forest of incompatible lisp implementations. I'm happy to see experimentation in the lisp space but it seems that fragmentation is only going to happen if everyone runs off into the woods to write their own incompatible lisp over things like syntax.

As for $SOME_HOST interop... a fair bit of the language is an artifact of the JVM. LOOP/RECUR is simply because the JVM is probably never going to support TCO (and while not required by a CL implementation it's nearly universal because it makes for efficient recursive programs... a style of program that is rather natural to lisps). The language doesn't have conditions and restarts because of the JVM (though I've heard it posited that it could be possible to implement them on top of exceptions).


Wish I could upvote more than once.


Honestly, I'm far more of a Schemer than a... Clojurite?Clojurist? Clojourneyman? I did try to make the switch to Common Lisp back in 2006, but I wasn't happy and went back to Scheme. Still, I'm far more interested in learning Clojure than giving Common Lisp another try. Here's what makes the difference for me:

1)Library support. With Clojure, it's a five minute import to get Bessel functions. When I asked about how to do Bessel functions in 2006, I was told to write it myself. I've heard things have become better since then, but I haven't been able to find any evidence that

2)Immutable data structures. Yes, this can be implemented as a library in CL. However, having it as the default means that I know every non-Java function I call isn't going to break that assumption. If I did find a Bessel function library, I can't assume that it's safe.

3)GUI support. In 2006, I needed to write a GUI application that ran on Windows, Mac, and Linux. PLT Scheme (now racket) had options available, but they weren't pretty. When I went to Common Lisp, I was first directed toward CLX, which wasn't native on Mac or Windows. Someone then suggested McClim, which still needed an X-server on Windows and now seems to be largely dead. It was then suggested that I write my own binding to WXwidgets. I considered that, but I'd then need to write a high level wrapper over those low level bindings.

Comparatively, from the little I've toyed with the Seesaw library from Clojure, it seems to be a beautiful way of handling GUIs.

Okay, I guess this comes down to another library issues.

4)Dotted pairs. The only use I've ever encountered for these is extremely fine tuning performance optimizations, but third party libraries loved surprising me with these at odd moments. I can see how Lisp-1 versus Lisp-2 might be a matter of taste, but I've never heard someone complain that how they missed dotted pairs when working in Scheme or Clojure. They may be a good argument, but I've never heard it.

5) Libraries. I'm sorry that I keep coming back to this point, but I guess it's a big one. Every time I tried to do something interesting in Common Lisp, the recommendation that I was given was to write low level wrappers to three different C libraries. For several of those projects, I found it easier to just cut out the middle man and write the whole damn thing in C. The rest of the time, I wound up writing Lisp that looked almost exactly like C.

Honestly, half of this is because I'm a mediocre programmer. I have no pretensions of greatness. If I was a great programmer, I could see how to make my own DSL that made the interaction of the libraries beautiful, instead of C with more parentheses. However, in scheme or clojure, I can usually find the work of another, better programmer, who has already made that DSL. In Common Lisp, I'm usually told to write it myself. I don't know if that's because all the other Common Lisp programmers are so brilliant that they all write DSLs all day or if it's just because they're all mediocre programmers like myself and no one knows how to do it.

6) Global variables. Every examples of idiomatic Common Lisp code I was delivered was littered with globals. This might be a stylistic decision, but it's one I've never liked. A third of my problems seemed to be solved by setting OPEN-NETWORK-SOCKET-AND-SET-FIRE-TO-PRINTER to 1 and STOP-PRINTER-FIRE to nil. I can see this reliance on globals if you're writing servers, where you have a long running application with lots of state, but I wasn't, so it just made the code harder to reason about.

7)Image based programming. I understand from the SmallTalkers that this is the best way to write code, but I don't get it. What always happened for me was that some global SWITCH-CHARACTER-ENCODING-TO-EBCDIC would get set at some point and all my code would now fail. With a file based language, I'd exit and restart to kill this accidental state and everything would be okay. With the image based code, I'd have to go through the assorted globals and find which one had changed.


Regarding image based programming. There is nothing preventing you from exporting your package(s) as a "change set". This change set can be imported into your start image. Any real globals would of course not reside in the change set, because it originated from a package. Maybe I'm missing your point.



>Bluntly, I don't know why Clojure was created as a new language instead of an advanced library over Common Lisp

I think you basically answered your own question :)

>JVM interop is compelling


But the thing is, Armed Bear Common Lisp (ABCL) already offers JVM interop.

If someone sat down and really massaged it, the currently clunky interop there could be just as shiny as Clojure.


Rich Hickey's previous projects to clojure were all about Lisp<->JVM interop (see http://foil.sourceforge.net/, but there is at least one other) -- so I think he found limitations to what you can do.


>But the thing is, Armed Bear Common Lisp (ABCL) already offers JVM interop.

Yes, a half-arsed, barely supported interop. And slow to top.

>If someone sat down and really massaged it, the currently clunky interop there could be just as shiny as Clojure.

I rest my case.


Yeah, they do. And there's quite many of them actually. :-) Clojure might be big in the startup bubble, but that's about it I'm afraid.


I'll use Clojure when it gets LOOP.


Well here's where you might start: https://github.com/tayssir/cl-loop

Although the community seems to prefer the port of Iterate: https://github.com/nathell/clj-iter


Isn't Loop just a big macro? Write it if you want it.


If you need someone to try a hand in supporting ruby, give me a hit, would gladly try to accomplish it.


I can't wait for that to happen, I learned Emacs for the sake of CL development... I was actually thinking of learning Clojure just to check out LT.


I'm not near any machines of mine that aren't Chromebooks. Does anyone know if the libudev.so.0 stuff is fixed? I don't see any mention of it in the change log, but I was really hoping they would have a fix for those of us not on Ubuntu so we don't have to symlink the new libudev.so.1 to so.0 just to use light table (yes other hacks exist, this was the most prevalent one...)


unforunately no. It's an issue carried over from node-webkit[1] and I'm not really a Linux guy :/ Someone could work on a fix for node-webkit, though and I'd pick it up in a heartbeat

[1]: https://github.com/rogerwang/node-webkit


Thanks for the quick response. I'll try to find some time to look into this. I know Chromium links to libudev for input device support so that it can do things like gestures, but I don't know that LightTable supports (will support?) them. It may be possible to do away with that linking but I may have to dig into the chromium code to do it.


I think Node uses it too and there's no way around that one I don't think.


When trying to download using chrome, I'm getting a warning, saying "LightTableWin.zip is not commonly downloaded and could be dangerous." Guess it is a false positive.


So as long as a piece of malware is commonly downloaded, you have nothing to worry about.


The really popular malware WILL have fixes in an antivirus/malware database ;)


It's a little disturbing to see that much user hand holding/prodding.


I might be missing something, but I feel like this is just reinventing IDEs that exist today (but are boo'ed by Sublime Text/TextMate guys.)

For instance, when it comes to Python, PyCharm (http://www.jetbrains.com/pycharm/features/index.html) seems far more powerful -- it provides live debugging/breakpoints (with the ability to change attributes of running code -- even for server code), code introspection, documentation browsing, refactoring, JavaScript debugging (integrated in FireFox), VirtualEnv support, tight integration with Django/Flask for templates, etc... And it's fast

So aside from the look and feel, what does LT have to offer?

The more tools the better, but I just wonder if anybody who has used a modern robust IDE can offer a comparison?


Fix and continue isn't live; its a start, but you still have lots of work to do in UX to display evaluation. I would try using LightTable before passing judgement.


The author mentions [1] (at the bottom, under 'key bindings') that light table uses codemirror[2] as the editor.

I am really amazed with how well codemirror emulates basic vim key bindings [3], as I prefer to use ctrl-c rather than escape and I often find that vim emulators either do not support ctrl-c or do not support it well.

[1]http://www.chris-granger.com/2012/04/15/light-tables-numbers... [2]http://codemirror.net/ [3]http://codemirror.net/demo/vim.html


Huge changes. Can totally use LT as main dev env for JS and Clojure code now. Thank you Chris for this release


Maybe I'm doing things wrong and I haven't seen anybody mention this, but ...

... all of my code is on remote machines. Either in a VM or on a server, far, far away.

Is there a way to use SFTP to open files for editing?


It's easily done in Linux and UNIX via sshfs (it's what I use in the same situation as yourself): http://en.wikipedia.org/wiki/SSHFS


you probably have to mount those.


Wow its really coming along. Only one thing is missing from me living in this full time with browser tabs and the like is that I use my screens in portrait mode and would prefer to be able to tear off a tab and have it live in another window and then on another screen.

I realise I am an outlier. That said I can always just manually refresh the browser window on the other screen which I currently do anyway.

I dont suppose anyone else has a method of dealing with this currently?


I do the same, plus a watch/live reload task.


I look forward to writing (essentially vim-) plugins for light table in javascript. Some day soon?

Extensions were mentioned on the blog about a year ago (http://www.chris-granger.com/2012/04/15/light-tables-numbers...), but as far as I can tell, they're still not here yet :(


The plugin architecture is something we have to be deliberate about given that it allows you to do literally anything we can do. I talk a little bit about the plan moving forward at the bottom of the post, but gist is that there's going to be one more public release, and then the private beta (for KS folks) is going to focus on really hammering out how we expose LT to plugins.


Is there a way to preorder in order to get into the private beta as well? I wasn't with the Kickstarter crowd. If plugins are as powerful as you say they are, I'm very interested.


Yeah, I found myself visiting the Kickstarter page today hoping there was some way I could fund the project months after it completed. Needless to say I couldn't. Seems like it would be a useful feature for projects like this - I doubt they couldn't find a use for more money.


The Double Fine Adventure guys are doing that, for an example of how it could work. They call the second round supporters 'slacker backers' [0].

I would also pre-order now if I could.

[0] http://www.doublefine.com/dfapay/


Can you comment in generalities on the scope of changes to LT's behaviour end users can expect to be possible by design, e.g. the entire stack is modifiable to the extent that Emacs (even the underlying elisp interpreter) is modifiable, only via a limited API like Sublime Text 2 has (which results in end users being reliant on major changes coming from the top down), or something else entirely?


Smalltalk and Lisp Machines are back!

Nice work.


If you're looking for the same kind of live reload web editing, I have such a plugin for Vim:

https://github.com/jaxbot/brolink.vim


nice!


Stupid question: "import matplotlib" is failing despite matplotlib being installed on my system (OS X) and working fine when I run python from the command line. I'm guessing it's something to do with my PYTHONPATH not getting imported properly. Does anyone have any idea how to fix this?

Edited to add: this is the first time I've properly tried LightTable and oh my god what a gorgeous piece of software. It's glorious. Just.. yeah. Job well done! :)


I just filed an issue that might be related: https://github.com/Kodowa/Light-Table-Playground/issues/469


I really want to use this, but unfortunately the performance is still painfully lacking. Excited for this to get a little further along and more stable.


Looks great!

Just confirmed matplotlib/pylab plotting working with Anaconda Python distribution. (To get LightTable to not use the system python, I had to go through some hoops... creating an environment.plist didn't seem to work.)

The dot-completion seems like it still needs work, but it's pretty neat to have an alternative web-based REPL front-end to the IPython kernel than just IPython Notebook.


Can you elaborate on the "hoops"? I am trying to get a similar thing working.


Well, it's not that much of a hoop. If you start LightTable from the command line, via "open /Applications/LightTable.app", then it gets your environment parameters, including PATH, which is the important one.

I tried to create a ~/.MacOSX/environment.plist file per the instructions here[1], but that didn't seem to work and I haven't bothered to fiddle with it more.

[1] https://developer.apple.com/library/mac/#documentation/MacOS...


Thanks for the tip. Got it working now.


It's really amazing, glad that I'm one of the backers when it's on kickstarter.

And I know it's shameless, but my LIVEditor project also allows you to "navigate to any page you want and start live modifying the it", I just made a 1-minute demo video here: http://youtu.be/t91IoDxo9aY


I have to admit it, I never expected Light Table to be able to reach this point. Kudos to anyone involved.


I will be watching Light Table much more closely after finally seeing the Python support. Awesome work!


I wish there was some way to set it up for use with other languages (ones that have Read-Eval-Print facilities.) I can't get very interested until I see that.

The UI font appears to be unchangeable. I can understand the motivation for that, but it renders pretty badly on my system.


I'm interested in writing a simple rest API using compojure as a learning exercise. Can anyone experienced give an outline of what a reasonable workflow would be to do this using light table? I see that light table can "connect" to my project.clj...


1. make a new lein project

2. fill in the dependencies in project.clj

3. open your src/core.clj (or whatever) in LT

4. start coding

LT will automatically launch a client and connect to it. In between lein will have seamlessly fetched the dependencies for you (this happens automatically each time you launch or relaunch a client).

You can do manual (C-Enter) or live (Instarepl) inline evaluation in any of your project file or even connect a new fresh repl to the client to experiment from scratch.


Would you then recommend focusing development around some unit tests and eval-ing them as you do work? (that's what I am trying so far, seems ok)


Precisely. This is at least how I do it.

It is also pretty nice to have an Instarepl where you can see live changes, either in your source files or in a separate repl. Don't forget that if your paths and namespaces match you can require your namespaces at will.


I'm normally not a screencasts kind of guy, but is there a good one for using the REPL to assemble, oh, say a web app in Compojure? I started doing a Clojure/Compojure tutorial the other day and I thought I was doing way too much restarting to get changes to take effect (using emacs/nrepl).


Are you using the wrap-reload Ring middleware? That seemed to make most restarts not necessary for me.


Nope. Thanks for the pointer.


Has anybody gotten the node.js connection working. I keep on getting 'In order to start a NodeJS client, you have to have node installed and on your system's PATH.' But, node is indeed installed, and in my $PATH. Running OSX with node v0.10.5


I have node in my global path, but it still won't run.

    The node process exited. 
    The node process you were connected to suddenly quit. Check the console for more information.
And the console says:

     Error: No protocol method IDeref.-deref defined for type null


I have the same issue as you do. Node is in my global path. However, the console says a little more:

rror: No protocol method IDeref.-deref defined for type null: at Error (<anonymous>) at cljs.core.missing_protocol (file:///Users/jk/.lighttable/js/bootstrap.js:1384:10)

Additionally, I was able to get the node repl to successfully connect and launch whenever I directed it at a JS file which was compiled from Coffeescript.


You have to set a global path.

I followed this and got it working.

http://serverfault.com/questions/16355/how-to-set-global-pat...


Absolutely fantastic. I spend about 30% of my time in Python and 30% in Node.js, using WingIDE and Aptana, respectively. I'm not going to abandon my current IDEs, but this has the potential to change my workflow significantly.


I hoped ST3 would replace Emacs, but Light Table seems more like it now...


Sublime Text will never be a plausible replacement for Emacs as its design does not encompass all of possibilities a lisp machine provides. Sublime Text is a plausible replacement for any tool which only targets text editing though. It has many converts or new users whose use case is only a text editor though, so to that extent Sublime Text has been successful.


I don't understand what you mean. ST3 is scripted in Python. If Python was as pervasive in ST3 as elisp is in Emacs, and provided similar concepts (buffers, regions, markers, modes, hooks, advices...), why couldn't it "replace"[1] Emacs?

[1] replace here means "being as powerful as", not actually converting Emacs users, most which are happy with Emacs..


In answering this I will ignore details specific to the two tools (such as how the implementations are modified), the merits of either, how they are used, and only compare their design goals.

It is true that both tools are mutable and that hypothetically their potential use cases will overlap entirely.

The reason this will not occur though is a consequence of one tool aiming to provide a general environment by design and the other tool aiming to provide a general environment for a specific use.

Less abstractly, consider the difference between having a factory which produces a specific item and having a factory which can produce any factory.

Possibly the specific item the factory produces is sufficient for the recipients of the specific item, and further that specific item may even make other items the recipient possessed moot.

However, the factory which can produce any factory can still (and possibly already has done so) produce the specific item.

Emacs' design (and Light Table's) is much more similar in breadth to the factory which produces other factories.

Sublime Text is more similar in scope to a factory which produces a single item.

The difference in design choice leads to Sublime Text and other text editors being comparable in features and it is also why Sublime Text can replace Emacs' text editing functions.

At the same time the design choice also leads to Emacs being a RSS client but Sublime Text not also having that functionality (or being reasonable to expect), despite the potential for the functionality to exist in both tools.

The difference between the two goals is why Light Table is much more intriguing to me than Sublime Text is despite the utility Sublime Text provides and how well executed Sublime Text is.


I aggree, but I still hope that ST3 could go Emacs direction....


@ibdknox- I wonder if you could comment on the the IPython frontend we see in this demo. I am very interested in the idea of inline javascript based plotting and am wondering if this was possible.


This is really cool. Are there plans for intellisense? Although I know that is hard to do well in dynamic languages. Also, any plans for instarepl in languages other than Clojure? Great work guys.


I am using OSX 10.8.3, and when I open the lighttable app, i see the lighttable logo/text and then it closes/crashes. Anyone had any similar issue? any know fix?

EDIT: Fix - sudo rm -Rf ~/.lighttable/


Where is the source code?



The integration with Chrome is a nice way to get information about objects in JavaScript. Are you planning to similarly make run/debugging powered auto completion for python?


How is it, if compared to IPython Notebook? Anyone familiar with both Light Table and IPython tried it yet?

[I'm Light Table backer, just want to know, if it is time yet to try it out... ;) ]


Very impressive demo.

So happy to finally see python support.

What is used for the javascript rendering? I assume since they are using the chrome dev tools they are embedding chromium into Lighttable?


I am fairly sure that Light Table is a node-webkit[1] app, so your assumption should be correct.

[1]https://github.com/rogerwang/node-webkit


It is indeed. Chromium + embedded NodeJS written in ClojureScript.

FTW.


It seems to be possible to use the Chrome PDF Viewer. This could be nice for LaTeX development.


They've written in the past that the UI is essentially a webview, so I think that's a fair assessment

edit: also, I've successfully nuked the app at least once by evaluating document.write (or similar) in the IDE. heh


Hard to tell until they release the source code (which is supposed to happen after the 0.4 release). The whole UI is actually rendered HTML using WebKit or a derivative for sure.


It looks amazing, but I haven't been able to get it to work since 0.2.

alert('foo');

Produces 'SyntaxError: Unexpected identifier'. I'm looking forward to the kinks being ironed out.


There's a bug for that one, https://github.com/Kodowa/Light-Table-Playground/issues/449

will get fixed tomorrow.


Is there a way to have it evaluate all the Python in my file so I don't have to go and manually evaluate each function?

Also my "return" is not updated automaticall.


it should eval it all for you the first time you open the file, but cmd/ctrl+shift+enter should eval the whole file. Though it won't return results for each individual thing. Alternatively you can also select the entire file and press cmd/ctrl+enter to eval the selection.


I keep getting - Failed to load resource: .lighttable/img/connectingloader.gif when I try to evaluate Python code. :(


This is really cool, I love the Vim bindings. Well done, I look forward to following this project as it progresses.


I'm getting a "Couldn't find node.js" error when trying to connect to a node app. node is at /usr/local/bin/node



This is awesome! I haven't used an IDE for a long time now but LT has shown enough to convince me to use one.


Just started digging in Clojure + ClojureScript, so definitely trying Light Table as well!


Please please please support Java in all of its glory and let me get rid of Eclipse!!!!!!


Hmm, I can not find that neat functions drag-drop layout from video...


Python support! Thank you Chris. Will certainly give it a shot.


Awesome... but PLEASE ditch that vertical side menu. It's one of the worst UX decisions I've ever seen and literally gives the user a headache.

Pleaseeeeeee


I like the vertical side menu. It saves valuable horizontal space, and adds a touch of class too.


...or give the user the ability to toggle between icons. I like how the panel opens on the left, but the text is maddening...


This is awesome! Way to go LT.


looking even more awesome. super excited to see Python support now.


hmm… no mention of search/replace? Whatever, I'll try it anyway.


[deleted]


Actually we haven't implemented replace yet. There's a few things like that that will either end up in 0.4.* releases or 0.5 at the latest.


Also, multi-line selection, please? =) That's probably the main thing that's keeping me in ST2 right now...


Yeah, multi selection has pretty much replaced my use cases for find/replace. And I work faster that way too.


If you're taking votes, I'd also like to vote for this. Having multiple cursors is like coding on crack.


Contrary to the others I don't care for multiselection.

But search/replace… even notepad, textedit and nano have it.

Anyway, I was initially convinced you'd never deliver and you consistently proved me wrong during the last months. Bravo and good luck!


This, Sublime Text is actually in my view a good looking and fast editor, with plugin support and multiselection. LT is now missing multiselection.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: