Yuescript icon indicating copy to clipboard operation
Yuescript copied to clipboard

not everything is an expression (most notably assignments)

Open heavyk opened this issue 1 year ago • 2 comments

hi, I've been using yuescript for a little bit now so I feel pretty familiar with the language. here are some example things that I thought should have worked:

-- parens not working
if (old_val = @v) != new_val
    @v = new_val
-- working
old_val = @v
if old_val != new_val
    @v = new_val

-- assignment not working
lala = (fn) ->
    print "fn:", fn
    fn(math.rand!)
lala listener = (val) -> print val -- left hand expression is not assignable
lala (listener = (val) -> print val) -- syntax error
-- working
lala = (fn) ->
    print "fn:", fn
    fn(math.rand!)
listener = (val) -> print val
lala listener

-- iter not returned
perm = (a) ->
    co = coroutine.create ->
        permgen a, #a
        return -- necessary cause no way to specify no return
    iter = ->
        code, res = coroutine.resume co
        res
-- working
perm = (a) ->
    co = coroutine.create ->
        permgen a, #a
        return -- necessary cause no way to specify no return
    iter = ->
        code, res = coroutine.resume co
        res
    iter
-- ideally, I'd like to write:
perm = (a) ->
    co = coroutine.create !->
        permgen a, #a
    iter = ->
        code, res = coroutine.resume co
        res

-- doesn't consider last expression of do-statement as module value
export default module = do
	{foo: true}
-- also, it doesn't think that the assignment is an expression
module = do
	lala = {foo: true}
export default module
-- working
module = do
	lala = {foo: true}
	lala
export default module
-- also works
export default do
	{foo: true}


in general I really like the language. I've got a lot of ideas as well for improvements to the language:

  • if x isnt nil (is/isnt keywords)
  • type val is "function" (compiles to type(val) == "function" instead of type(val == "function"))
  • type val is \function (single backslash is single word text)
  • !(var) -> ... (no return)
  • !-> ... (no return)
  • comma on next line extends function:
    lala (v1, v1) ->
        print v1, v2
    , var1
    , var2
    

lastly, the online compiler is quite valuable for seeing what yue compiles to and I really like it. however, the text area only allows me to click on the top. this can easily be fixed by setting prism-editor__container to have min-height: 100%. (seen below) edit: that should be 'min-height' (screenshot invalid)

image

cheers!

heavyk avatar Dec 04 '23 12:12 heavyk

Thank you for the time you've spent on this project!

  1. I have ever thought of implementing the assignment expression syntax in the Python way, and many cases should be taken into account carefully. Maybe I can start with changing the if-assignment that is currently implemented to the better "Walrus operator" form from Python. Although it will break some old codes, but I think that worth it.
  2. I like the is syntax as short for type(x) == "typeName", and we got two ways to do it. One is to make is a keyword, and this will break some Lua codes using "is" as variable name. Another is to make code in var is number form a special syntax for type checking, and code like is number will still compiles to function call is(number). We have to decide the better implementation.
  3. You can make use of a macro to create the "no-implicit-return" function for the moment, but using a macro may lead to missing the line mapping information for debugging.
macro no_ret = (func)-> "#{func}\n\treturn"

a = $no_ret (var)->
  print 123

Maybe we can pick other symbols to declare a "no-implicit-return" function since f! -> f1! (var) -> print var is currently valid code. 4. The following expression list started with comma in new line could be implemented, maybe an indent rule should be applied, I will dig into that later. 5. Thanks for your fixing solution for the web compiler, it should be working now with the new commit!

pigpigyyy avatar Dec 07 '23 07:12 pigpigyyy

  1. a long time ago, I used to use LiveScript, which I find I liked the syntax pretty well (he uses ~> instead of => for bound functions). he has some good ideas. the tests for the commas can be found here.
  2. the point of the 'is' syntax is to give precedence to the 'is' operator higher than '==', so it's over the parens; so, for example type lala is 'number' compiles to type(lala) == 'number' (right now type lala == 'number' compiles to type(lala == 'number')
  3. ah yes, I just started to use macros to do stuff like $is_num, $is_fun, $is_str, etc. (as a replacement for the 'is' syntax). writing return is OK for now... f! !-> f1! (var) !-> print var is not valid syntax though (no space between ! and ->)

I really want to help out with the language, however c++ is a real barrier for me. I've looked through the code and though I can get it to compile now, I simply cannot understand the C++. so there's no easy way for me to help. I'd like to write the compiler like this, for example to ensure the last line is always returned. anyway, I looked at moonscript, and it uses LPeg, which does make the parser easier to understand. I may take moonscript and try to get all of yue's tests passing on it, as an exercise.. I'll let you know if it happens.

cheers!

heavyk avatar Dec 13 '23 07:12 heavyk