11 ms·
Wren is a small, fast, class-based concurrent scripting language
- pull_my_finger 4y agoIt seems weird to market it as a "concurrent" language. A lot of mainstream general purpose language from the past 30 years have some form of coroutine/generator. Off the top of my head Lua, JS, Ruby, Go, Python etc all have them and Go being an exception which has actual threads iirc. This may be a "me" issue, but hearing it marketed as a "concurrent" issue seems to lead you to believe has real parallel execution.
- pmontra 4y agoI like about everything except the leading underscores for _fields and for __static_fields. They look really bad, a remnant of the 80s. I understand that one of the goals is keeping the VM small but there must be another way.
- rr888 4y agoIs it time for some new characters like an emoji to signify attributes like this?
- mgrandl 4y agoYou could setup a font with special ligatures for something like this, without changing the convention…
- dataangel 4y agoPython does it and is still very much alive. It's also idiomatic in C++.
- Cyberdog 4y agoAnd PHP still has __construct() and friends. It still looks like a remnant of the '80s, though.
- AlchemistCamp 4y agoPopularity doesn’t mean something isn’t “a remnant of the 80s”, as the previous poster put it.
- bobsomers 4y agoIt's definitely not idiomatic in C++. The standard reserves names starting with an underscore and a capital letter or containing double underscores in any scope, and identifiers beginning with an underscore in the global namespace. Most style guides I've seen that use underscores in identifier names use trailing underscores deliberately to avoid colliding with names reserved by the standard.
- agentwiggles 4y agoUgh, I hate this convention. I will grudgingly admit, after spending the last year in a C++ codebase, that it makes reading code somewhat easier to have a clear indicator of whether we're looking a class variable or not, but something about that unnecessary character bugs me.
- renox 4y agoI work in C++ and removing the confusion between local variables and class members with only one character looks to me as a very good idea!
- b3morales 4y agoIt's a neat little language. It was created by the author of [Crafting Interpreters][0]; the language in the book (Lox) is essentially a slimmed-down Wren for teaching. [0]:https://craftinginterpreters.com https://craftinginterpreters.com
- keyle 4y agoAnd author of the excellent https://gameprogrammingpatterns.com https://gameprogrammingpatterns.com before that!
- chaosprint 4y agoCool. Can this be embedded in Rust? Does it support wasm32 (probably this is how the web demo runs?)?
- stefanos82 4y agoSeems like it https://github.com/pwoolcoc/wren-rs https://github.com/pwoolcoc/wren-rs
- 5d8767c68926 4y agoNote that the last commit was 8 years ago (when Rust hit 1.0).
- stefanos82 4y agoWell, basically I copied the second link from https://github.com/wren-lang/wren/wiki/Language-Bindings https://github.com/wren-lang/wren/wiki/Language-Bindings just randomly; I didn't think to check the release date to be honest with you, my bad. The other Rust projects seems more updated, like https://github.com/Jengamon/ruwren https://github.com/Jengamon/ruwren was last updated in May 9.
- hwers 4y agoWhats wasm32 (vs just normal wasm)?
- lioeters 4y agowasm32 uses 32-bit pointers for memory addresses, instead of 64 (wasm64). > Why have wasm32 and wasm64, instead of just using 8 bytes for storing pointers? > A great number of applications don’t ever need as much as 4 GiB of memory. Forcing all these applications to use 8 bytes for every pointer they store would significantly increase the amount of memory they require, and decrease their effective utilization of important hardware resources such as cache and memory bandwidth. > The motivations and performance effects here should be essentially the same as those that motivated the development of the x32 ABI for Linux. > Even Knuth found it worthwhile to give us his opinion on this issue at point, a flame about 64-bit pointers. https://webassembly.org/docs/faq/#why-have-wasm32-and-wasm64-instead-of-just-using-8-bytes-for-storing-pointers https://webassembly.org/docs/faq/#why-have-wasm32-and-wasm64... --- > The x32 ABI is an application binary interface (ABI) and one of the interfaces of the Linux kernel. It allows programs to take advantage of the benefits of x86-64 instruction set..while using 32-bit pointers and thus avoiding the overhead of 64-bit pointers. https://en.wikipedia.org/wiki/X32_ABI https://en.wikipedia.org/wiki/X32_ABI --- > It is absolutely idiotic to have 64-bit pointers when I compile a program that uses less than 4 gigabytes of RAM. When such pointer values appear inside a struct, they not only waste half the memory, they effectively throw away half of the cache. https://www-cs-faculty.stanford.edu/~knuth/news08.html https://www-cs-faculty.stanford.edu/~knuth/news08.html
- ogogmad 4y agoHaven't classes -- as things which house methods and fields together -- gone out of fashion? I think the same thing has happened with inheritance. The ontological problem of "does the knife cut the cucumber" or "does the cucumber get cut with the knife" seems serious. The "is-a" relationship is also problematic, because does a square inherit both from rhombus and parallelogram?
- Cyberdog 4y agoWhat on Earth makes you think it's gone out of fashion? Pretty much all of the most widely-used languages have classes or analogues, if not full OOP.
- ogogmad 4y agoI thought that privileging the first argument of a function, which is all that separates a method from a function, was understood to be an ugly hack. I thought that this was acknowledged now, and only legacy languages are stuck with it. Julia, Rust and Go don't do this. So it's going out of fashion and becoming legacy. IOW, there was never really a difference between obj f(obj); and class obj {obj f();} so the whole idea was a mistake. Likewise, obj.f() should be synonymous with f(obj) and the fact that in some languages it's not is evidence of a poorly thought-out abstraction. See multiple dispatch for the death blow. There's also a discussion elsewhere here about operator overloading, and how arithmetic operators don't behave like methods.
- germandiago 4y agoFrom a mathematical point of view it can seem like that. But now pick a language like Nim, whcih also has a crazy regex to match symbol equality, and unigorm call syntax etc. and the IDE completions are much harder to find.
- Jtsummers 4y ago> I thought that privileging the first argument of a function, which is all that separates a method from a function, was understood to be an ugly hack. I thought that this was acknowledged now, and only legacy languages are stuck with it. Julia, Rust and Go don't do this. So it's going out of fashion and becoming legacy. [emphasis added] What? Go has methods which "privilege" the first argument to functions: https://go.dev/tour/methods/1 https://go.dev/tour/methods/1 func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } Though it moves the argument out of the argument list and between the func keyword and method name. Rust also has a notion of methods: https://doc.rust-lang.org/rust-by-example/fn/methods.html https://doc.rust-lang.org/rust-by-example/fn/methods.html Were you thinking of other languages?
- dataangel 4y agoIs it statically typed?
- Cyberdog 4y agoNo: https://wren.io/try/?code=G4QwTgBAZg9jEF4ICIBG5kChbyQFgCZMBlATwGcAXAUwFsA6ABzAEsA7SgChwEog https://wren.io/try/?code=G4QwTgBAZg9jEF4ICIBG5kChbyQFgCZMBl...
- IshKebab 4y agoI have yet to find any nice easy "normal" (like Typescript or Dart) statically typed languages that can be easily embedded. In the Rust space there's Gluon which is statically typed but has a really weird syntax and is functional, and there's Rhai which is really quite nice but dynamically typed. I guess static type checking is probably more work on its own than writing an entire dynamically typed language.
- goodpaul6 4y agoI’m currently working on Tiny [0], a small statically typed programming languages which is even more minimal than Wren. [0] https://github.com/goodpaul6/Tiny https://github.com/goodpaul6/Tiny
- IshKebab 4y agoLooks interesting. How is the type just `array` in that example though? Doesn't it have to be an array of something?
- goodpaul6 4y agoInterestingly, given the minimal core of the language, arrays are not built in (this is something I'm looking to change, of course). As such, the "array" type is just an opaque type exposed via the C binding API. Given that there are no generics at the moment, this array API works with "any" values (similar to "any" in e.g. TypeScript).
- 4y ago
- xscott 4y agoWren seems pretty elegant, but it makes the same mistake a lot of languages do when it comes to operator overloading. If you put the binary operator as a method on the first object, then there isn't a simple way to have "builtin_object <operator> your_object". For instance, Wren doesn't provide complex numbers, so you aren't going to get a nice syntax for "1/z" or similar. I could make similar examples with scalar multiplication for vectors, matrices, or Numpy-style arrays, etc... Python and other languages have fallbacks to work around this, but Wren does not. And really, I think of binary operators as 2 argument functions, not methods on the left object.
- TazeTSchnitzel 4y agoThis is an area where typeclasses (as they're known in Haskell) or traits (as they're known in Rust) really shine.
- fiddlerwoaroof 4y agoOr multimethods (as found in CL/Clojure/Dylan/Julia)
- fiddlerwoaroof 4y agoCan’t you solve this particular issue with extension methods the way Kotlin and C# do?
- sirwhinesalot 4y agoExtension methods rely on overloading, they don't use dynamic dispatch.
- fiddlerwoaroof 4y agoYeah, but typically in these languages operators don’t really need dynamic dispatch. (Although, I agree this causes surprising results).
- tamsaraas 4y agoI think this is one of the best languages that i ever seen before. All interested by me concepts are covered, that open ability to write different complex logic for manipulating data. WoW. Thank you very much for all of that! This is really great, and has powerful potential to become inner-script language for many different projects where must be ability to write some kind of macroses, scripts inside the main enveriopment (game engines, game emulators) Good job! I feel that you have wide experience in scripting languages that developed inside some big project for inner purposes inside a big app.
- Kyrio 4y agoOriginally made by Bob Nystrom [1] who now works on Dart, it is now maintained by ruby0x1 who is a game developer and most importantly creator of a game engine that uses Wren as a scripting language [2]. Unfortunately Luxe is still not publicly available (closed beta), which I admit is a bit of a frustration for me as I've been following development for a few years, but it does show a lot of promise and in the meantime I've become a happy user of Godot. I keep Wren in the back of my mind as an easy-to-embed scripting language in cases where you could integrate Lua (which Wren outspeeds) but not LuaJIT. [1] https://news.ycombinator.com/user?id=munificent https://news.ycombinator.com/user?id=munificent [2] https://luxeengine.com/ https://luxeengine.com/
- boondaburrah 4y agoOh that's good to know, especially for games which sometimes must go where JIT cannot (consoles, iOS other than javascript)
- Fr0styMatt88 4y agoTIC-80 [1] (the open-source Pico-8-like fantasy console) supports writing games in Wren. [1] https://tic80.com/ https://tic80.com/
- dagmx 4y agoAs a complete aside, Wren was also the name of the in-house renderer at Rhythm and Hues. Used in award winning films like Life of Pi before they went bankrupt. Anyway not really related, but it’s the first thing that popped into my mind since it was my first gig.
- hot_gril 4y agoI like this a lot. The interoperability with C is especially cool, one of the reasons I liked Rust too. And it covers concurrency well, which scripting languages usually don't. Edit: Originally complained about lack of async/await but realized that fibers cover the use case for that.
- quechimba 4y agoWren seems great. Last time I needed to embed a language I used Lua, and I haven't had the need since then, but I've been thinking for years that next time I'll use Wren. It looks really nice. I skimmed through the code a few years ago and it was surprisingly small and seemed very well structured
- grungy 4y ago> lovingly-commented Yeeesh! Sorry don't want loving comments, just meaningful concise ones where needed, thanks.
- tomcam 4y agoPreviously (with comments; several other appearances with no discussion): https://news.ycombinator.com/item?id=23660464 https://news.ycombinator.com/item?id=23660464
- dang 4y agoThanks! Macroexpanded: Wren is a small, fast, class-based concurrent scripting language - https://news.ycombinator.com/item?id=23660464 https://news.ycombinator.com/item?id=23660464 - June 2020 (54 comments) The Wren Programming Language - https://news.ycombinator.com/item?id=16945227 https://news.ycombinator.com/item?id=16945227 - April 2018 (30 comments) Wren: a small, fast, class-based concurrent scripting language - https://news.ycombinator.com/item?id=11611661 https://news.ycombinator.com/item?id=11611661 - May 2016 (39 comments) Wren: A classy little scripting language - https://news.ycombinator.com/item?id=8826060 https://news.ycombinator.com/item?id=8826060 - Jan 2015 (61 comments)
- imtringued 4y agoI thought about using wren for Minecraft modding but threw that idea away because I don't have the time to build a JIT Java bytecode compiler that can compete with Rhino. I think wren is a much better choice than JavaScript or Lua.
- Uptrenda 4y agoWould definitely appreciate a more in-depth commentary on 'fibres' vs coroutines. Since it seems like there is a difference in 'scheduling' and Wren is using fibres. What are the pros and cons?
- chalst 4y agoAgreed. Janet uses the term fibres to describe its green threads managed with a Lua-like coroutine interface. Is that like what's going on here?
- germandiago 4y agoI am integrating Wren into a game via wrenbind17. My codebase is C++. So far it is relatively smooth. Wren itself and the fibers support and language in general are simple and great tools that have helped me a lot. But I also want to list things I would like to be smoother to integrate. This is probably half of it Wrenbind17 limitations more than Wren, Idk, but here I go. 1. Cannot expose enum constants easily. 2. Inheritance: if I create a subtype of A, being that subtype B and I creatr in Wren a B subtype, I cannot call A methods. This is painful. 3. Exposing classes was pretty easy BUT exposing state from C++ was a bit more challenging. I had to do something like (by generating code): ``` var State = null class StateSetter { static set(State s) { State = s } } ``` On the C++ side a variable pf that type is exposed, set is called on the C++ side and the var State imported. 4. In Chaiscript callbacks can be exposed directly with no wrappers. In Wren I am not sure it is possible. Had to wrap stuff (look at Wrenbind17 fot an example). 5. No static properties or constants made a lot pf boilerplate to expose just enums (had tp wrap in functions each enum value. All in all Wren is working pretty well. Even I could expose nlohmann json as its own jso type and make it work natively with zero casting as it should work in a dynamic language.