12 ms·
GorillaScript
- Aqwis 13y agoToo bad it doesn't have list comprehensions. That's something I sorely miss when writing most mainstream languages apart from Python. (I know CoffeeScript has them.)
- cameronkknight 13y agoActually it does have list comprehensions. You just use a for loop (or any loop) as an expression and it evaluates to an array.
- egonschiele 13y agoWow, some of these features sound really cool! As a small complaint: After seeing about a dozen compile-to-JS languages, I don't care about the full list of features anymore. Please add a big note at the top saying how this is different from other compile to JS languages. Why save all the good stuff (typing, promises, currying) for the last half of this massive page?
- atroche 13y agoI came here to say this.
- X4 13y agoI second that, just WOW. Someone wasn't satisfied with removing semicolons and curly braces and fixed the ENTIRE language instead. WOW!!
- roryokane 13y agoI filed a issue for you on GitHub: https://github.com/ckknight/gorillascript/issues/100 https://github.com/ckknight/gorillascript/issues/100
- imslavko 13y agoI have no claim to be an experienced developer or so, just asking for opinions: doesn't this huge number of complex features implemented in modern programming language give you a feeling of something being wrong? And why?
- X4 13y agoNo it doesn't. It gives you freedom to do things naturally, but you will only understand how to solve a problem naturally, when you've understood "programming in general" or "Computer Science", without specifics to a programming language. To take fear away, you can easily create very very complex stuff with a single language feature. Think about QBASIC, one would think that you cannot do anything except some command-line programs with it. See the complete opposite: http://www.pcworld.com/article/2033318/black-annex-is-the-best-qbasic-game-youve-ever-seen.html http://www.pcworld.com/article/2033318/black-annex-is-the-be...
- nnq 13y agoYou can make the same argument about "something being wrong" with a language like Scala. Some people like "slim" languages like C, Go, Clojure, Python, others like "fat" ones like C++, D, Rust, Scala, CL. It's just a matter of taste. I tend to like the "slim" ones more but maybe a "fat" language is better suited to wrangle the browser-based-dev can of worms.
- MichaelAza 13y agoThis seems like the Python of compile-to-JS languages in much the same way CofeeScript is the Ruby. Not a big fan of Python but I can see this becoming popular with Python WebDevs. I kinda hope this doesn't become a trend though, every web development enviroment spawning its own compile-to-JS language. I feel that there are too many such languages already.
- ealexhudson 13y agoInteresting, I would have said CoffeeScript was more pythonic than this. It certainly doesn't remind me of Ruby, and to the extent that it's a different syntax for JavaScript than a different language, scoping is different but in practice you don't notice things that are very different in Python.
- nnq 13y agoI think it's closer to "the Scala of compile-t-JS languages" :) ...last time I checked Python didn't have macros and syntax for currying, function composition, piping etc. and its TIMTOWTDI philosophy seems closer to Ruby. Honestly, the macros section scared me out, especially the "there are five types of macro syntaxes" (...this is as far away from the pythonic way of doing things as one can get) but this seems the most promising compile-to-Js language I've seen.
- cameronkknight 13y agoMacros can be scary. The need for five different syntaxes is because in a non-homoiconic language, positioning and syntax matter, so having an infix operator would be defined differently from a call-like macro. They all act fundamentally the same, it's just how you define the syntax of how they are used that is the difference.
- Too 13y agoPython has functools.partial for currying. Not built into the syntax but in the standard lib.
- dreen 13y agoThats what I was thinking too. I would like to simply see Ruby/Python compile into JS instead. It has been done actually (not sure about Ruby) - don't know how well it performs though.
- twiceaday 13y agoThere is a small typo in "The outer this can also be captured _be_ appending".
- roryokane 13y agoFiled a pull request fixing this: https://github.com/ckknight/gorillascript/pull/101 https://github.com/ckknight/gorillascript/pull/101
- mistercow 13y agoWhile this is an interesting effort, I can't help but be squeamish about the sheer volume of JS that gets emitted (due to type checking) for what seem like small amounts of input.
- cameronkknight 13y agotype-checking and such features can be easily disabled by sticking const DISABLE_TYPE_CHECKING = true at the top of your file. It's handy to have in development vs. production.
- tel 13y agoWait, the type checking isn't static?
- cameronkknight 13y agoCurrently, no. I do plan on adding warnings (not errors) on a statically-calculated type issue. One thing is that I don't plan on it erroring if you call a function with a value whose type might be an "any" type or a "union" where it expects a specific type. If there's some overlap, it would allow, to make things easier and give the programmer the benefit of the doubt. Thus, the following would compile without warning: let double(x as Number) x * 2 let repeat(x as String) x & x let fun(x as Number|String) if is-number! x double x else repeat x let fail(x as Boolean) // this should fail at compile-time double x I could write the compiler to be a lot smarter and have it track types through conditional branches (which would be very hard, but possible), or allow it in those cases where it is possible that the types overlap. I also might add a "cast", i.e. a runtime type check. I'm not sure what the best syntax for it would be, but it would act like the following: CAST(x, Number) // validate that x is a Number or throw a TypeError CAST(x, Number|String) // validate that x is either a number or a string, otherwise throw TypeError CAST(x, Number, 0) // validate that x is a Number, otherwise evaluate to 0. Of course, in the cases where `x` could not fit the type requested, then that could error at compile-time. I would love some feedback on this, especially from the perspective of "what would I use to help me develop", not "I need my program to be 100% statically type-safe without having to do any testing".
- buster 13y agoNow this one really looks like a nice language!
- mythz 13y agoWhoa, this actually looks really good. terse, robust and safety first, whilst still packed with some high-level features.
- modarts 13y agoKinda like C# ;)
- cameronkknight 13y agoYes, I take a lot of inspiration (with some leeway for personal taste) from Delphi and C#, so I have great respect for Anders Hejlsberg - who I'm now competing with since TypeScript.
- nnq 13y agoWith such a kitchen-sink list of features, I can't believe he left out named parameters (seriously) and refinements (sarcastically). Though this is definitely the best compile-to-JS language and I'd choose to use it if I'll ever feel safe enough using anything else than plain Javascript.
- anonymous 13y agoNamed parameters would be a good addition, but I wonder how feasible it is to implement. If the signature of the function is known at compile-time it's trivial, but what about expressions like `a.b.c.foo(x=2, y=3)`? You'll need some sort of trampoline which takes the function to call, the value of this, a list of the unnamed parameters and a dictionary of the named parameters, then use reflection on the function to call to construct a list of arguments for .apply; and I'm not sure if javascript saves the names of the function's parameters to be available for reflection. Meaning each defined function might have to be an object lugging around some __signature property and named parameters would only work for your own functions.
- byroot 13y ago> I'm not sure if javascript saves the names of the function's parameters to be available for reflection Yes an no. YOu can't access it directly, but if you call toString() on a function you'll get is source code as a string so you can parse it. Prototype do that to handle the special $super parameter [0]. But most modern minifier rename function parameters and local variables, so it's not a good idea. [0] https://github.com/sstephenson/prototype/blob/master/src/prototype/lang/function.js#L38 https://github.com/sstephenson/prototype/blob/master/src/pro...
- cameronkknight 13y agoFor named parameters, this is the best one can do in JavaScript without constructing a fully static type analyzer: let use-named({ name, age }) -> use-named(name: "ckknight", age: 25) For refinements, what are you referring to?
- 13y ago
- grn 13y agoLooks very interesting! The features that caught my attention are: * immutable values * cascades * try/catch/else/finally * promises * async * optional typing * curreid functions * generics
- marcfawzi 13y ago"bitand" for bitwise & is weird
- cameronkknight 13y agoBitwise operators for JavaScript are unused except in special cases, as JavaScript really doesn't handle bitwise as one might expect. Everything is cast to either int32 (or uint32 in the case of >>>) and then recast back into a Number (8-bit IEEE-754 floating point). Due to their relative lack of use, freeing up the symbols to represent something else seemed prudent.
- marcfawzi 13y agohow about _& instead of the lengthy and typo prone "bitand"
- yoklov 13y agoI've seen them get quite a bit of use in graphical code, which is, well, actually fairly common in JS. Code that uses bitwise operations looks fairly ugly as is. Hav e you considered enabling them with a prefix or suffix? E.G. ^$ instead of bitxor, or >>$ instead of bitrshift...
- cameronkknight 13y agoThat could be possible, you could even do it today, if you wanted: macro operator binary ^$ ASTE $left bitxor $right There are also operators for `and`, `or`, `xor` which act logically. `not` which does a boolean invert. So there are `bitand`, `bitor`, `bitxor`, `bitnot` which fit well as working bitwise instead of logically. I suppose the outliers are `bitlshift`, `bitrshift`, `biturshift`, but it does somewhat make sense to keep the `bit` prefix because it casts to int32 and because its operations are inherently bitwise.
- marijn 13y agoEverything is weird the first time you see it.
- bsaul 13y agoMassive work.congratulation for achieving this. My main concerne is with optionnal typing ( which is my only real concern with javascript at the moment ) : it says that types are checked at runtime. Does this mean i still have to run unit tests that goes into all my code before i can be sure i don't have a type error ?
- cameronkknight 13y agoYes, you would, at least in the current state of things. I do plan on adding some compile-time checking (without getting in the way), but it's not there yet.
- dlsym 13y ago1 & 2 == "12" - Now THAT I call unexpected behavior. :-/ Interesting language though.
- pogden 13y agoIn what way is that unexpected, given then & is string concatenation?
- arcatek 13y agoWell, because '&' is probably not a very good choice for a concatenation operator since it has a very different meaning in most of languages. Most developers would overlook such an error. Of course you can say that since it is defined as such, it's not a issue, but then we could say that any Javascript "Wat" behavior is also defined in the spec.
- protomyth 13y agoI would say that & is a fine choice (much better than +) for a concatenation operator. It allows numbers to be built like strings in an interesting way and keeps the meaning of the & consistent. It really is past times that every language needs to conform to the choices made by C.
- 30thElement 13y ago+ has problems as string concatenation, but that doesn't make & a good choice. We still use a lot of C-ism's because people are used to them, and any deviations from C-like behavior, which at this point could be called "common behavior" just increases the learning curve and the cost of a context switch. Personally, I like Perl's period(.) for string concatenation, but I think it can too easily get lost in the line, especially for more complex stuff. $foobar = "foo" . $bar->{'bar'}
- protomyth 13y agoPeriod has a general meaning of ending a sentence. At this point in our history, people willing to clear the deck of C-ism should be encouraged. I think the learning curve is worse when folks imitate C for no reason other than computer tradition as opposed to building something that feels tied together. We ditched a lot of older habits with C, we should continue the path.
- nubela 13y agoWhy would I use this over coffeescript/underscorejs?
- JuDue 13y agoYes I'd like to know too. As the top post mentions, the documentation really needs to hightlight the benefits over established popular libraries.
- anonymous 13y agoDashed-identifiers is probably my favourite feature. I've personally defined the <leader>f chord to emit an underscore in vim just to save myself the trouble of reaching all the way for a shift and a dash.
- noelwelsh 13y agoLooks interesting. The section on "Optional Typing" is too brief. Type inference is mentioned, but there are no details on how the type system functions and what a failure of type checking means. It seems one can't name types, which is odd and will lead to a great deal of repetition.
- cameronkknight 13y agoTypes are allowed to be any of the primitive types (e.g. Boolean, Number, etc.), null, undefined, any custom "class", a specifically-typed array (e.g. [Number] for an array of numbers), or a specifically-typed object (e.g. {x: Number, y: String}). I do plan on being able to alias the typed object as an "interface", just haven't gotten around to that. A failure of type checking generally means you get an early runtime error, though I plan on reworking things to catch more at compile-time (while still not being a pain).
- tel 13y agoHow do types work with objects and classes? Can you subtype?
- cameronkknight 13y agoYeah, class Child extends Parent
- cameronkknight 13y agoIf anyone would like to look at the slides for a presentation I did on GorillaScript, here you go: http://ckknight.github.io/gorillascript-presentation/ http://ckknight.github.io/gorillascript-presentation/ In it, I discuss some of the design decisions. Sadly, there wasn't any video, so I don't actually go in-depth in the slides themselves.
- goldfeld 13y agoThis looks like CoffeeScript had a baby with Rust, and I'm seriously tempted to switch from the former for my latest project. It has all features for which I am still considering adding specialist libraries to CS (promises, macros, and a bunch of ES6 stuff.) Insanely great work! The latter parts of the slides where one slide == one feature helped me have a feel for the language better than the text docs.
- bliker 13y agoI would prefer some compiled JavaScript ECMAScript 6 that and could be compiled into compatible JS. So I can use all the goodness like classes and iterators. Without having to deal with polyfills. Please somebody...
- aeosynth 13y agohttps://github.com/google/traceur-compiler https://github.com/google/traceur-compiler Requires a runtime, though.
- bliker 13y agoIt can be precompiled but it has not been optimized to do so: https://github.com/google/traceur-compiler/issues/307 https://github.com/google/traceur-compiler/issues/307 It seems the project is not very active.
- aeosynth 13y agoIt requires a runtime even after compiling: https://github.com/google/traceur-compiler/wiki/CompillingOffline https://github.com/google/traceur-compiler/wiki/CompillingOf... > The code generated by Traceur depends on a small runtime library containing Javascript code for things like creating classes, handling spread arguments, etc. To use code compiled from Traceur, you'll need to include that too.
- rattray 13y agoThat doesn't sound so bad if it works well, though, right? Kind of like including jQuery so you get cross-browser code.
- ville 13y agoHow about Traceur? https://github.com/google/traceur-compiler https://github.com/google/traceur-compiler
- gregwebs 13y ago
- mwcampbell 13y agoI'm curious about why ckknight started this project instead of contributing to Dart. I see that the syntax is more Pythonic than C-ish. What else distinguishes this language from Dart?
- cameronkknight 13y agoDart reinvents a full type system for itself, with its own environment and paradigms, and if you want to cross-compile to JavaScript instead of running in a dart VM, you have to ship a huge swath of code with it to get it working. GorillaScript works with the JavaScript type system instead of against it, at least as well as it can, including supporting nice future additions like Map, Set, and WeakMap. GorillaScript tries to work within the JavaScript landscape as best it can so that there is as little of a disconnect between GorillaScript and JavaScript as possible.
- Zecc 13y ago>> x and= y - Same as if x then x := y I'm having trouble imagining when you'd need to do this. But oh well.. >> There is also a short syntax for single-word strings that also convert dashed-names to camelCase just as normal identifiers do. I'd like to see an example of this. I don't think I quite understand what it's meant to do. >> Binding access I would have preferred: f@obj (arg1, arg2, arg3) for function application over: f@ (obj, arg1, arg2, arg3) Other that that, I can certainly appreciate the huge amount of work involved in creating this and I wish them success.
- cameronkknight 13y agoand= isn't all that useful, I agree, but it would be odd to leave out given that there's or=, ?=, ownsor=, etc. \alpha-bravo-charlie == "alphaBravoCharlie" Well, since GorillaScript doesn't require parentheses for invocation, you'd need to have some delimiter between the context and the arguments or have to wrap one of them. Why not simply just use "," as the delimiter and then you can treat it as if doing .call/.apply?
- Zecc 13y ago> Well, since GorillaScript doesn't require parentheses for invocation, you'd need to have some delimiter between the context and the arguments or have to wrap one of them. Well, I was trying to think why you'd even need a delimiter. I thought the absence of the comma between the context and the first argument would disambiguate: f@x (a, b, c) would be written as: f@x a, b, c // Comma between a and b While: f@(x a) (b, c) would be: f@x a b, c // No comma between a and b Then again, a call like: f@ a b c d, e would be ambiguous, so on second thought I think you've made the right decision. Heck, even the non-ambiguous cases seem easier to mentally parse with the comma there. So I retract from what I said. I should have thought this through before posting. Edit: I see you've also added the example of dashed-names to camelCase conversion to the page. Thanks, that helps. Edit2: formatting.
- mhb 13y agoWhen using this for development, what is the workflow? I write something in GorillaScript, compile it and run it in the browser. Is there anything like (GS) source level debugging so that I don't need to figure out the correspondence between the GS source and the JS in order to, for example, set a breakpoint?
- bliker 13y agoThat is where source maps come into place. Not sure about support for GS though.
- cameronkknight 13y agoGorillaScript has full support for Source Maps, as any good compile-to-JS language should.
- girvo 13y agoThis seems to fix every small issue and even a few large ones that I had problems with in JS! It seems like it will be super easy to integrate with my current "build tools" for the few dynamic languages I run (built into Komodo as macros and plugins). Heck, I could probably write the build tools plugins in Komodo WITH GorillaScript. Of course, not quite the same as a brand new self-hosted compiler, but I'd like to think that it's circular-referency is adequate to be in the vein of functional programming tradition :) I was never excited about Coffeescript. This is JavaScript: The Good Parts And Even The Best Brand New Parts
- cameronkknight 13y agoI'm very happy you're excited about it. The best thing you could do for me now is to use GorillaScript to make something. Anything. Something big, something small, something with fancy features or minimal ones. I want you to think along the way "how could my life be easier?" "Better typing? Terser syntax? More verbose syntax? Easier async support? Some other fanciful feature?" Then, file issues on the GitHub tracker with your ideas to make GorillaScript better for you. Or join us on IRC at irc.freenode.net at #gorillascript. I (ckknight, author of GorillaScript) try to be there as often as I can, but I do have a life outside of IRC, for now...
- alifaziz 13y agoThere is also Embedded GorillaScript for templating http://ckknight.github.io/egs/ http://ckknight.github.io/egs/
- nilved 13y agoIs this the same ckknight who made PitBull, Parrot etc?
- cameronkknight 13y agoYeah, I stepped away from the Lua world to work on JavaScript-related stuff.
- mmgutz 13y agoThe same guy who used to hang out on boo irc? Wonder if that's where the macro ideas came from.
- cameronkknight 13y agoYeah, I hung out there. Also contributed a bit. No, most of my macro ideas come from Scheme.
- gregwebs 13y agoWow, I wish this is what coffeescript was. This has most of the niceties of coffeescript and adds immutability, types, and macros. I will end up sticking with TypeScript though for anything at work since the type system has more capabilities right now and it is just Javascript with types so it is very simple to use for those with Javascript experience.
- omaranto 13y agoWhat do you mean when say that you wish CoffeeScript was this? I mean GorillaScript exists, so if you prefer it to CoffeeScript then use it rather than CoffeeScript.
- masukomi 13y agoThe difference is that CoffeeScript has a massive amount of mindshare, integrations, and tooling. GorillaScript may be better than CoffeeScript but that doesn't mean that it's even remotely close in terms of day-to-day usability. Because CoffeeScript got there first (and was decent) it's got a huge head start on ANY other competitor.
- wiremine 13y agoYes, but that's like saying Perl got there first before Python or Ruby. GorillaScript, CoffeeScript, TypeScript, etc. all basically use Javascript as a platform, and there should be room for all of them in the long run. (Or, at least room to let the market sort out which ones they like the best). BTW, this got me thinking: are the Javascript envine vendors (V8, etc.) doing anything to make it easier to write languages like GorillaScript or CoffeeScript? Or is it all up to the language designers?
- cameronkknight 13y agoThey have made serious effort with developer tooling, especially with Source Maps.
- mr_luc 13y agoHoly cow. It's built on macros, and macro-friendly! And I can use it with the node.js ecosystem! As a guy who built his own npm-installable macros.coffee, [0][1][2] I am torn. I love macros enough that I felt I needed to have them in JS-family languages, which have few metaprogramming options outside of tricks on 'this', which is why, when I saw that CoffeeScript had clean syntax and a relatively clean AST, I made it my "learning node/npm" project to add them. On the other hand, my project is simple because it depends on a fragile hack: running a deep-copy on a chunk of AST for 'quote'. It's a fragile hack that jashenkas could break with a single well-placed closure, and as I promised on my project page, "If you want to ... build a substantially more 'heavy-duty' implementation, I'll probably end up using yours." This isn't an implementation in CoffeeScript, but it's better -- it's actually built into the language (as macros work best as a core language component; once you have 'em, it's easiest to write your language with them). I'll have to try out GorillaScript and see what it actually feels like to write code in the language, allowing for the fact that its syntax may not be as pretty as coffeescript yet. But I wouldn't be surprised to find myself using GorillaScript this time next year. Macros++. ----- 0) github.com/mrluc/macros.coffee 1) http://mrluc.github.io/macros.coffee/docs/macros.html http://mrluc.github.io/macros.coffee/docs/macros.html 2) https://npmjs.org/package/macros.coffee https://npmjs.org/package/macros.coffee
- cameronkknight 13y agoInteresting work. Once I refactored GorillaScript to be pretty much fully macro-driven, it made everything super-nice to deal with. Every single syntax construct in GorillaScript is a macro, even `if` and all that stuff.
- aerolite 13y agoWhile this is actually really awesome, I think a lot of the nastiness of JS can be dealt with by using a good JSHint plugin for your text editor (that highlights errors/etc as they happen). Hoisting, function scope, ==, var, using variables without defining them, etc - it'll catch many things.
- cameronkknight 13y agoIf I ever write JavaScript, then I definitely use JSHint. It doesn't help with some things such as immutable local bindings, type checking, not having to worry about hoisting, or any of the nice syntax features you get with GorillaScript, which is why I see the benefit.
- __david__ 13y agoSo overall this is an interesting take on Javascript. I like that much of it gets precompiled away (constants, etc). I'm not so fond of "&" being string concatenation. I like Perl6's "_" better, it reads well. Also: > || - or, can no longer be used with and unless one group is in parentheses Seriously? Do you require the "+" and "" operators to have parentheses around them? Why do people think order of operations is hard with "and" and "or"? I really* don't get it (and always turn off compiler warnings about that when working with C). Also, "ownskey" is a bit of a mouthful. Why not ".?" ("?." would be "get key if object isn't null")?
- cameronkknight 13y agoMost of the time, string concatenation is unnecessary with interpolation: "$alpha $bravo" means alpha & " " & bravo. The reason `and` and `or` are best in parenthesized groups is that it creates confusion in the precedences otherwise. asking someone what `alpha and bravo or charlie` means can be confusing if there's no obvious grouping (like a standard mathematical operator's) giving `and` more precedence than `or` or the other way around. You actually can use `!.` as an "owns access", as used in `alpha!.bravo`, which means `if alpha ownskey \bravo then alpha.bravo`. And yes, `?.` means an "existential access", as used in `alpha?.bravo`, turns into `if alpha? then alpha.bravo`. You can also mix these with `?!.` and it works as expected. :)
- __david__ 13y agoThe thing about "and" and "or" is that there is obvious grouping--it stems from boolean logic where there is an order of operations ('or' is like '+' and 'and' is like '\*'). There's really no excuse to pander to people that can't or won't memorize the order of operations for boolean logic. BTW, I don't like coming across super critical, but this is a pet peeve of mine. This particular issue really gets under my skin (I always pass -Wnoparenthases to gcc). Overall I am very impressed with Gorillascript. I love the macros, the functional programming stuff and the basic terseness of it all.