[HN Gopher] Wren is a small, fast, class-based concurrent script...
       ___________________________________________________________________
        
       Wren is a small, fast, class-based concurrent scripting language
        
       Author : ahamez
       Score  : 87 points
       Date   : 2022-08-28 20:02 UTC (2 hours ago)
        
 (HTM) web link (wren.io)
 (TXT) w3m dump (wren.io)
        
       | ogogmad wrote:
       | Haven'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?
        
         | newobj wrote:
         | Only the misapplications you give examples of have gone out of
         | style, I'd say.
        
           | ogogmad wrote:
           | How do you know when it's a misapplication? What do these
           | constructs actually model?
        
             | [deleted]
        
         | Cyberdog wrote:
         | What 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 wrote:
           | 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.
           | 
           | 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.
        
             | Jtsummers wrote:
             | > 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                 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
             | 
             | Were you thinking of other languages?
        
             | lifthrasiir wrote:
             | You can have multiple `f` with different "arguments" (if
             | you consider a receiver a part of arguments) without the
             | full multimethod, which is actually pretty hard to get it
             | right and only one language out of your examples (Julia)
             | does that. Other two languages (Rust and Go) fully retain
             | classes, slightly obscured to fit with traits and
             | interfaces respectively.
        
             | jakelazaroff wrote:
             | obj.f() shouldn't necessarily be synonymous with f(obj)
             | though. How would the latter case handle private fields,
             | for example?
        
         | ok_dad wrote:
         | > The ontological problem of "does the knife cut the cucumber"
         | or "does the cucumber get cut with the knife" seems serious.
         | 
         | Kinda both! The knife (aka: the "Cutter") can perform a "Cut"
         | action on any object (aka: the "Cutable"), but the Cutable
         | objects have to receive the Cut action and determine if the
         | Cutter has enough "Cutter.Strength" to Cut the Cutable.
         | 
         | I think the failure of OOP is applying it to things that aren't
         | appropriate or creating a Factory pattern that causes over-
         | abstraction. OOP in itself isn't bad, much like PHP or Windows
         | has their place even though they get shit on all the time, but
         | the lack of care applying OOP (or any other pattern or
         | architecture) is the bad part.
        
         | mananaysiempre wrote:
         | You seem to have conflated several different things.
         | 
         | - Single dispatch--having a single distinguished "receiver" for
         | each operation determine how to perform it. Can get very
         | awkward when the problem domain does not work that way
         | (algebraic operations of all kinds), but it's still nearly
         | universal outside languages with CLOS heritage (Clojure,
         | Julia).
         | 
         | - Having classes be distinct from (though possibly a subset of)
         | objects. Less elegant, but also nearly universal except for
         | rare holdouts (JavaScript). Nystrom's book explains his opinion
         | on this. Incidentally, it took people until 2005 (!) to figure
         | out[1] how to make multiple dispatch work in a prototype-based
         | (that is, classless) setting.
         | 
         | - Objects, that is self-contained bundles of state and
         | behaviour. (Arguably a subset of single dispatch.) Wonderful
         | when it fits, painful when it doesn't (syntax trees and other
         | places when you want to match pieces of structure). Nystrom's
         | explanation of how the Visitor pattern addresses this is very
         | good, and pattern matching in Scala and (recently) Python works
         | roughly along these lines in a setting of (mostly) pure
         | objects.
         | 
         | Unfortunately, when you want both the set of verbs and the set
         | of nouns to be extensible (the "expression problem"), something
         | more powerful is needed, as both pure objects and pure
         | functions struggle here. "Protocols" in Clojure and Swift are
         | among the ways people are trying to address this, but I can't
         | say there is a singular accepted solution yet.
         | 
         | - Subtyping, having some groups of thingies be included in
         | other groups of thingies ("is-a", or rather "every-*-is-a-*").
         | Widely accepted to be necessary in one way or another. Rarely
         | fits into a tree of inclusions--"diamonds" are fairly common.
         | 
         | One issue that was understood relatively late is "variance":
         | instead of an operation that takes Xs and gives Ys, you can
         | substitute an operation that takes Xs _or something more
         | general_ ("negative position", "contravariant") and gives Ys
         | _or something more specific_ ("positive position",
         | "covariant"). In particular, you can _get_ the side of a
         | rhombus or something more specific (thus e.g. getting the side
         | of a square), but _set_ the side of a rhombus or something more
         | general (thus e.g. simultaneously setting all sides of a
         | quadrilateral at once). Therefore _if_ your operations are
         | packaged together with data into objects, and _if_ those
         | objects are mutable, squares cannot be a subtype (nor a
         | supertype) of rhombuses.
         | 
         | - Implementation inheritance. Has indeed gone out of fashion,
         | comparatively speaking, especially the painful diamond kind
         | (unlike same for subtyping, which is as necessary as ever).
         | Remains a convenient shortcut in most languages that do
         | objects, outside of a few obscure systems that provide more
         | powerful replacements (parents in Self, delegation in Snit,
         | aggregation in pre-WinRT COM).
         | 
         | [1] https://dl.acm.org/doi/10.1007/11531142_14
        
       | dataangel wrote:
       | Is it statically typed?
        
         | IshKebab wrote:
         | I 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.
        
           | 10000truths wrote:
           | Have you checked out AngelScript?
           | 
           | https://www.angelcode.com/angelscript/
        
           | goodpaul6 wrote:
           | I'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
        
             | fm77 wrote:
             | Very interesting!
             | 
             | BTW: I think I found a typo: "MATCH2("+=", PERCENTEQUAL);"
             | -- should be "%=" ??
        
         | Cyberdog wrote:
         | No:
         | https://wren.io/try/?code=G4QwTgBAZg9jEF4ICIBG5kChbyQFgCZMBl...
        
       | chaosprint wrote:
       | Cool. Can this be embedded in Rust? Does it support wasm32
       | (probably this is how the web demo runs?)?
        
         | hwers wrote:
         | Whats wasm32 (vs just normal wasm)?
        
         | stefanos82 wrote:
         | Seems like it https://github.com/pwoolcoc/wren-rs
        
           | 5d8767c68926 wrote:
           | Note that the last commit was 8 years ago (when Rust hit
           | 1.0).
        
             | stefanos82 wrote:
             | Well, basically I copied the second link from
             | 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 was last updated in May
             | 9.
        
       | xscott wrote:
       | Wren 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 wrote:
         | This is an area where typeclasses (as they're known in Haskell)
         | or traits (as they're known in Rust) really shine.
        
           | fiddlerwoaroof wrote:
           | Or multimethods (as found in CL/Clojure/Dylan/Julia)
        
         | samatman wrote:
         | I'm surprised to hear that, given how closely Wren's semantics
         | resemble that of Lua's.
         | 
         | Lua uses the left metatable's metamethod for two tables or
         | userdata, or the metamethod if the binary operator has a
         | primitive on one side of the argument.
         | 
         | This gives elegant results at the expense of some
         | implementation complexity: there's no mechanism to figure out
         | what's happening inside the metamethod, all you know is that if
         | both sides are metatable-able, you're in the left side's
         | method.
        
         | fiddlerwoaroof wrote:
         | Can't you solve this particular issue with extension methods
         | the way Kotlin and C# do?
        
         | mncharity wrote:
         | I _really_ look forward to a language with first-class explicit
         | algebras, with operators, laws, equality, types. Rather than ad
         | hocery on multimethods, or kludgery slathered thick over single
         | dispatch, or the ever popular  "you just can't get there from
         | here".
         | 
         | "1 is not an object; + is not a message"... I'm failing to find
         | the quote, but it dates back like 40 years to smalltalk, and
         | yet here we still are.
        
       | dagmx wrote:
       | As 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.
        
       | Kyrio wrote:
       | Originally 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
       | 
       | [2] https://luxeengine.com/
        
       | tamsaraas wrote:
       | I 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.
        
       | pmontra wrote:
       | I 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.
        
         | dataangel wrote:
         | Python does it and is still very much alive. It's also
         | idiomatic in C++.
        
           | Cyberdog wrote:
           | And PHP still has __construct() and friends. It still looks
           | like a remnant of the '80s, though.
        
       | b3morales wrote:
       | It'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
        
       ___________________________________________________________________
       (page generated 2022-08-28 23:00 UTC)