Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

not everything is an expression (most notably assignments) #158

Open
heavyk opened this issue Dec 4, 2023 · 2 comments
Open

not everything is an expression (most notably assignments) #158

heavyk opened this issue Dec 4, 2023 · 2 comments

Comments

@heavyk
Copy link

heavyk commented Dec 4, 2023

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!

pigpigyyy added a commit that referenced this issue Dec 7, 2023
@pigpigyyy
Copy link
Owner

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!

@heavyk
Copy link
Author

heavyk commented Dec 13, 2023

  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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants