123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- RAKU is a scripting language that resembles Engish somewhat.
- However it is a stealth lisp with smalltalk like semantics.
- In Lisp you would say (function1 arg1 (function2 arg2))
- In C you would write function1(arg1, function2(arg2));
- In Raku you will write function1 arg1 be function2 arg2 so
- attack the greater green gorgon with the large axe
- # Core problem: in most languages, arguments of a function are not only
- # delimited, but also the start and end of the function call
- # are indicated somehow, so that calling several functions in one statement
- # is possible. Similarly for message passing.
- # C-like:
- # foo(a, b, c)
- # foo(a, bar(b , c) ,d ,e)
- # Lisp-like:
- # (foo a b c)
- # (foo a (bar b c) d e)
- # What I'd like for Raku is drop the outer ()
- # foo a (bar b c) d e
- # Here the newline at the end, or the . make is clear the statement is finished.
- # However, calling functions still requires a special delimiter.
- # Unless if the parser knows that foo and bar are functions/methods/verbs.
- # Then it can distinguish between foo and bar and a b c d e.
- # But then it still can't see where an inner call ends and the top level
- # one begins: VERB NOUN PREP VERB NOUN PREP NOUN EOL ->
- # is this VERB(NOUN , VERB(NOUN, NOUN)) or VERB(NOUN , VERB(NOUN), NOUN)?
- # Without an end-of call delimiter the parser cannot know.
- # For the simple case of VERB NOUN PERP NOUN EOL
- # the EOL acts as the "end of call" marker, but it can't be used twice.
- #
- # I checked Inform 7 but it's a huge language with many unnecessary
- # complexities. It's simpler to solve the delimiter problem by using short words.
- #
- # an as at ax be by do go if of in is it me no of or ox so to up us we
- #
- #
- # set foobar to be add 10 to 10 so
- # set foobar to tally add 10 to 10 end
- # for i from 0 to be size foo so then do
- #
- # end
- # do / sub / block ... so / end / done -> block
- # be / run / call ... so / end / done -> sub-call, parenthesis
- # list / array ... so / end / done -> array/list value
- # act / define WORD [NAME [PREP NAME] BLOCK-> method definition on first NAME, which should be a type or instance. If none is given, "me" is used.
- # use NAME -> variable declaration takes values of arguments give to block if any.
- # nil / nothing / none / -> nil value
- # true / false / yes / no -> boolean value
- # return -> method return
- # yield -> block return
- This is unambiguous in IO or Potion:
- OBJECT METHOD1(ARG1_1, ARG1_2, ...) METHOD2(ARG2_1, ...) METHOD3 EOL
- # Inversed, apart from the parameters this becomes:
- METHOD3 METHOD2(ARG_2_1, ...) METHOD1(ARG1_1, ARG1_2, ....) OBJECT
- #
- # So io/potion ish
- Bob name append(" and ", Jane name) println
- # Would invert to
- println append(" and ", name Jane ) name Bob
- # now substitute the non-words with words
- println append of " and " with name Jane end name Bob
- # or if we use and for method chaining
- println and append " and " with name Jane and name Bob
- # So io/potion ish
- Bob hp decrease(Bob hp times(10) divide(Bob hpmax))
- # Would invert to
- decrease(divide(hpmax Bob) times(10) hp Bob) hp Bob
- # now substitute the non-words with words
- decrease tally divide of hpmax Bob end times tally 10 end hp Bob end hp Bob
- # or if we use and for method chaining
- decrease tally divide tally hpmax Bob end and times tally 10 end and hp Bob end and hp Bob
- # Conclusion, mere complete inversion is undesirable because the sequence
- # becomes unclear, what happens last is set first.
- # What is desirable is that like in English the verb comes before the object,
- # but only once, UNLESS it's prettier after. So it's better to start out
- # quasi-procedural
- decrease(hp(Bob), divide(times(hp(Bob), 10), hpmax(Bob)))
- #
- decrease hp of Bob by call divide call multiply hp of Bob by 10 end with hpmax of Bob end
- # of course that sucks somewhat. Probably it would be split up.
- # but that's the pricve toi pay to keep thing sipmle.
- # Requiring a call/end before most method/function calls resolves the
- # bracketing problem, and allows multi-word names, without a symtab.
- set newhp to hp of Bob
- multiply newhp by 10
- divide newhp by hpmax of Bob
- # So, raku is a small english like language with an OOP like syntax,
- # but no symtab lookup that happens only at runtime.
- # The next question is then, how much syntax to provide.
- # Since, unlike TCL, I can't use pure string substitutons, some built in constructs are needed.
- # However, these can be limited to Smalltalk-level constructs.
- # No if/while/etc is really needed, these can be methods in stead.
|