[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)
 
web link (wren.io)
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 
| 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)