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.