pigpigyyy / Yuescript

A Moonscript dialect compiles to Lua.
http://yuescript.org
MIT License
460 stars 39 forks source link

I like to request some features to make YueScript easier to copy code and use with AI assistant code like ChatGPT and Github Copilot, Tabnine! #152

Open GokuHiki opened 1 year ago

GokuHiki commented 1 year ago

Well... I use YueScript daily to write tools and script games as a hobby, but I also work in other languages like Python, javascript, C# and GDScript as a dev. I extend use Github Copilot and sometime ChatGPT. The AI really helpful but they just keep suggest with Python or Lua code. It is a chore to convert them back to YueScript. It is the same when I want to 'borrow' codes online.

Then one idea pop into my mind, why not make YueScript more AI and copy friendly by support more Python, Lua or other lanagues common syntax, notation and make it easier to convert code to YueScript. I think it will be a great feature for YueScript and make it more popular. Here are some I think will be helpful:

  1. Support create list like table with syntax: arr = [] YueScript only support [] in list comprehension like Python. It is kind of a wasteful syntax and it is like a chore to must convert all [] => {}. Support [] make code look better, easier to see, AI Copilot friendly and easier to copy, convert from code of other languages like: Python, javascript, json, GDScript, etc.

  2. Support Lua table syntax: {key = val} It copies Lua's code table or accepts AI's suggested code without the need to edit it would be nice. And it is a nice style, even GDScript supports it then why won't YueScript support it?

  3. Support declare function style like: function myfunction(parm1, param2) or func myfunction(parm1, param2) or def myfunction(parm1, param2) would be nice. It is a common syntax in many languages like Python, Lua, GDScript, etc. It looks better than myfunction = () ->. Yuescript is very nice but I think that humans and AI prefer it more.

  4. I like to write yuescript to make some local tools to process my assets. My OS is Windows, I prefer to use YueScript/Lua over bat/cmd. It would be nice if YueScript supports more template string because "${exe} #{arg1} #{arg2}" is not good on Windows: exe ad arg1/arg2 can have space in the path and require quotes with '"'. It would be nice if YueScript supports raw template string like:

    os.execute [["#{exe}" "#{arg1}" "#{arg2}"]]  -- that maybe confilct with current yuescript raw string
    -- or adopt Python style raw string
      os.execute """
        "{exe}" "{arg1}" "{arg2}"
      """
    -- or adopt js style
      os.execute `"${exe}" "${arg1}" "${arg2}"`
    -- or just add support template to '' string as
      os.execute '"${exe}" "${arg1}" "${arg2}"'
  5. Add support 'var' keywords like javascript, GDScript: with feature hoisting as JavaScript's default behavior of moving declarations to the top of functions or global scope. It solves the problem of using a variable before it has been declared without need to use local *:

    a = ->
    print "a"
    b!
    b = ->
    print "b"
    a!  -- attempt to call a nil value (global 'b')

    It is the pain when writing utility scripts that have many functions and depend on each other

  6. Add 'elif' as 'elseif'. Well... I code a lot in python, so I make a lot of silly mistake like use 'elif' in Yue.

Thank you and regards!

pigpigyyy commented 1 year ago

Then one idea pop into my mind, why not make YueScript more AI and copy friendly by support more Python, Lua or other lanagues common syntax, notation and make it easier to convert code to YueScript.

Yes, I can start with supporting Lua syntax right in Yuescript. Maybe just make lua a keyword and make the following Lua code ends with an extra end.

f = (tb)->
  sum = 0
  for item in *tb
    sum += item

  lua
    local data = {
      valueA = 123,
      valueB = "ABC"
    }
    function tb:print()
      for i, v in ipairs(self) do
        print(i, v)
      end
    end
  end

  print "back to Yue"
  sum
  1. When writing Yuescript, I wanted to write something like arr = [] or tb = [1, 2, 3] many times. I think this syntax won't conflict with any thing.
  2. The full Lua syntax shall be supported. I think we can targeting full Lua 5.4 syntax which can cover all the syntax in older Lua versions.
  3. The alising syntax for declaring function just like you said is AI friendly, but not that necessary for human to write the exact same things in two forms. Maybe with other inline languages support. We can care less about how the AI would work with Yue.
  4. This idea seems to work.
    -- or just add support template to '' string as
      os.execute '"${exe}" "${arg1}" "${arg2}"'
  5. This behavior will lead to bad programing practice so that Javascript added let and const works like the Lua variable scoping rules rather than the same as var. You may look into the discussions over the var scoping problems.
  6. Maybe just solve it by adding inline Python syntax support.
GokuHiki commented 1 year ago

Thanks for your consideration!

It would be nice if Yue can use [] and support inline lua syntax!

But I don't think adding inline Python syntax support is necessary and too much work need to implement and it don't benefit much when Python syntax similar but not better Yue when runtime Python too different to lua. I think you don't really need to burden yourself with this over complicated work. I would satisfy will only elif keyword alias.

I agree that use var is a bad practice. Well... I guess there are no solution for Lua/Yue forward declare function orders:

-- file: utility.lua
local function trim(s)
  return strip(s, " ")
end

local function strip(s, char)
  return s:gsub(s, "^" .. char .. "+", ""):gsub(s, char .. "+$", "")
end

local utility = {
  trim = trim,
  strip = strip
}

-- file: test.lua
print(utility.trim("  abc  ")) -- [ERROR] attempt to call a nil value (global 'strip')

Thank you and regards!

pigpigyyy commented 1 year ago

Got a little problem for list syntax with []. Currently in Yuescript:

with tb
  -- this is a valid indexing syntax inside a "with" block
  -- so we have to use [1,] as a list with only one element
  print [1]

-- here represents closed intervals for range comparison
if value in [1, 10]
  print "1 <= value and value  <= 10"

-- here for list values checking, support syntax of [20, 30] as list literal may lead to confusion
elseif value in {20, 30}
  print "value is 20 or 30"
GokuHiki commented 1 year ago

I think the in-range syntax is not easy read and to much confusion when use bracket and parenthesis together [), and the worst is that easy break syntax highlights. It would be better to use the compare operators instead with in-ranges syntax. And the best thing is it look realy good with font ligature code.

a = 5

if a in <=1, 10>=
  print "a is in range from 1 to 10"

if a not in <=1, 10>=
  print "a is not in range from 1 to 10"

if a in <0, 11>
  print "a is between 0 and 11 with open intervals"

if a in (1, 3, 5, 7)
  print "checking equality with discrete values"

And the with syntax. Well... I do not use it much but I guess use [x,] would not too bad. It is not many case that we would code an array with only one element, and we can use {x} as well so there are no problem with the syntax.

Thank and regards!

pigpigyyy commented 1 year ago

The in-range symbols were introduced from mathematics symbols. Yes it seems to be weird for a programing language. I just picked them because they cost less character to type but I got that it is requiring more familiarity with mathematics writing. Maybe

a = 5

if a in <=1, 10=>
  print "a is in range from 1 to 10"

if a not in <=1, 10=>
  print "a is not in range from 1 to 10"

if a in <0, 11>
  print "a is between 0 and 11 with open intervals"

if a in (1, 3, 5, 7)
  print "checking equality with discrete values"

or

a = 5

if 1 <= a <= 10
  print "a is in range from 1 to 10"

if not (1 <= a <= 10)
  print "a is not in range from 1 to 10"

if 0 < a < 11
  print "a is between 0 and 11 with open intervals"

if a in (1, 3, 5, 7)
  print "checking equality with discrete values"
vendethiel commented 1 year ago

Operator chaining like the 2nd part is the most natural and already exists in other languages.

GokuHiki commented 1 year ago

The first solution doesn't look nice with the font code ligatures: image

The second solution is more natural similar to compare logic as result lua codes and is the one I would recommend.

SkyyySi commented 1 year ago

For the [] list syntax, I would recommend having it disallow non-integer indexes. This would both make the feature have an actual function in the language (as supposed just to being another way to write the same thing) by providing a little bit of protection from accidentally using a dictionary table in a place where only array tables are supported, as well as enforcing a somewhat consistent usage for it. For the range syntax: I'm also with the syntax of a < b < c, though one thing to consider is that the expression, when put into Lua, would also be valid syntax, although I don't know of any library that requires this specific form of overloading; for regular numbers, it translates as a < b < c --> boolean < c --> error. Lastly, more of a general thing: While I do think that these are changes for the better, I don't think that them being more "AI friendly" should be a reason. ChatGPT fundamentally doesn't know/understand Yuescript (it sucks at vanilla Lua already from my experience). While Yue might somewhat look like Python at first glance, the languages are totally different when you look closer. This would not really make it easier - if anything, it would make it more difficult since now the code might be syntactically correct, but still completely wrong (by using the wrong libraries for instance).

GokuHiki commented 1 year ago

Well 1 < x < 3 is valid both python and lua. Look at the code below that as Yue or Python:

x = 2
res = 1 < x < 3  # True in Python, Error in Lua/Yue.
print(res)

Lua/Yue only work with res = 1 < x == true. Python look at the whole expression as one, while lua only calculates from left to right. While this express useful in python and have very little meaning in Lua, but there are no right or wrong here. The important thing here is what benefits us the most. Well... there is no doubt that python is the winner here. Uhm, in many case that 'in range' expression is not very much useful in first place if it make conflict with lua syntax.

About AI, large model AI don't need to know about language at all, they know about patterns in your text and what it maybe meaning (or not at all). Then they generate some random text for us. Only a fool would accept it as it is. It not your code, it is garbage, but garbage have it own useful if you know how to handle it. The important thing here is how much useful that random text is, how little that I need to edit it to make the code my own. The fewer keystrokes I need to types the better! Instead of fix syntax; fix logic; ..., if I can reduce the fix syntax then it would be a big help.

I use Github-copilot not because of how smart it is but because it is faster to edit something than write the code from zero. It just like how we choice to not code in notepad.exe but VSCode, Emacs, VIM...

Well... AI is just a tool. The same as code editor we use. AI suggestions is no different with editor autocomplete. In the end it total depends on us to choice what code we write, but if we can make it work better with Yue, then why not?

I love Yue, and I want to see it continue evol and adapt. Thanks and regards!

pigpigyyy commented 1 year ago

Added chaining comparisons and list syntax [] with disallowing key value pairs in it.

list_with_only_one_element = [1,]
tb = [
  1
  2
  3
  abc: 123 -- will report error here
]
[a = 1. b = 2] = tab_to_be_destructured
chrsm commented 1 year ago

There's no need to homogenize languages here. One consistent syntax is better than programmers being able to do different things when it suits them.

Nearly all suggestions here make the language more complicated syntax wise for no reason other than to suit someone using AI tools that don't actually understand the language and therefore serve no benefit.

GokuHiki commented 1 year ago

Uhm... of course there will be no homogenize languages here because Lus is an oddball one, so is Yue. I agree that consistent syntax is best but... that is not enough. There is a reason that things like syntactic sugar existed, it is to make dev lives easier. Well... a lot of people welcome it while many detest it. Yue is compiled to Lus code. Compared to Lus that Yue are expressive, extremely concise and has a lot of features.

But in other words, Yue is a language that bundles a lot of sweet syntax sugar for Lua. Because of that there is a limit for what Yue can do about runtime. But Yue can continue to improve by further adopting and improving its syntax while cafefully considering the pro/con.

Yue is not a popular language, so not many people will care to give an opinion about it. While I can perfectly write any Lua codes if I must/want to. But I chose to use Yue because it is fast, expressive and concise. I love Yue, see the problems with it and try to give some suggestions to make it more pleasing and faster to work with. It sure benefits me, then maybe it can benefit other people too.

I am not a fool who uses things he doesn't understand. I fully understand Lua/Yue but I work a lot with JS, Python so my head screams painful when read/write the same arr = {} and dict = {} in Lua/Yue. I guess I am not the only one who feels that way.

And I try my best to give opinions about syntax wise only, to not ask for a weird feature that just complies to a Lua code function that must be implemented by the user.

chrsm commented 1 year ago

I agree that consistent syntax is best but... that is not enough. There is a reason that things like syntactic sugar existed, it is to make dev lives easier. Well... a lot of people welcome it while many detest it.

Is this not something that can be made better for you specifically by using macros?

But in other words, Yue is a language that bundles a lot of sweet syntax sugar for Lua. Because of that there is a limit for what Yue can do about runtime. But Yue can continue to improve by further adopting and improving its syntax while cafefully considering the pro/con.

Yue is not a popular language, so not many people will care to give an opinion about it. While I can perfectly write any Lua codes if I must/want to. But I chose to use Yue because it is fast, expressive and concise. I love Yue, see the problems with it and try to give some suggestions to make it more pleasing and faster to work with. It sure benefits me, then maybe it can benefit other people too.

Nothing wrong with that at all. That's what I'm doing here, too. I use Yue heavily for personal projects and scripts, just like you. I'm giving my personal opinion.

I am not a fool who uses things he doesn't understand. I fully understand Lua/Yue but I work a lot with JS, Python so my head screams painful when read/write the same arr = {} and dict = {} in Lua/Yue. I guess I am not the only one who feels that way.

I didn't say you are a fool, nor that you don't understand it. I said the tools you are using do not understand it. That is the source of the problem, not the language. Why not improve the tools you use to better utilize the language? None of these changes will improve your actual editing experience.

And I try my best to give opinions about syntax wise only, to not ask for a weird feature that just complies to a Lua code function that must be implemented by the user.

As mentioned above, nothing wrong with that. I'm doing the same, just voicing my opinion.

One last thing on your previous comment:

The important thing here is how much useful that random text is, how little that I need to edit it to make the code my own. The fewer keystrokes I need to types the better! Instead of fix syntax; fix logic; ..., if I can reduce the fix syntax then it would be a big help.

Don't commit broken code :) This is PEBKAC, not the language's fault.

pigpigyyy commented 1 year ago

As a maintainer of Yuescript project. The more user opinions given to me the better dev decisions I can make to do a better maintenance or improvements. I appreciate your heavy usages @chrsm with Yuescript project. So that maybe more specific usage case with details can better convince me there are better ways to dev more features or bug fixes.

So back to this thread.

Do you think list table syntax like arr = [] and later discussed chaining comparisons like 1 <= a <= 10 are necessary and useful? These two features were implemented in version 0.20.0, Maybe you can have a try in Web compiler or test them in your project. And what do you think about inline Lua codes syntax? Do you think just leaving it to the macro function is enough?

pigpigyyy commented 1 year ago

Since we are just sharing a pretty small community. I think I can push things to go faster once I got vacant time, and actually try various ideas to see if they will work out.

GokuHiki commented 1 year ago

I very like the syntax arr = [] and thinks it useful with someone like me. It keeps my mind at ease because of my background working a lot with JS, TS, json and python. I think it's very easy to read and understand, especially for a large code base with a lot of nested config objects. I can see why some people don't like it and want to keep it as Lua vanilla as possible. But it matters a lot for someone like me who need to write arr = [] and dict = {} countless time, even a hundred times every day.

About 1 <= a <= 10 or in range expr, I don't have much opinion about it because, well... honest speaking, there are seldom that I need to check if a variable in range when I code every day. But one day, when I need and try to use in range expr, it created a lot of closure anonymous functions in the performance critical update loop cause a lot of GC and FPS drops. Well... you know that Unity+Lua is use a lot in mobile game for fast hotfix/hot-reload solution or dynamic generic frameworks. So I try to avoid it. But if I need to choice, I would prefer min <= ver < max over ver in [min, max) because it's more readable and I can use it in other languages without any problem. The only time I see that use [) is in Unity3D Assembly Version Define expressions: https://docs.unity3d.com/2021.3/Documentation/Manual/ScriptCompilationAssemblyDefinitionFiles.html

And I use my custom Yue code highlight and some custom tools for Yue, because of that, maintaining it with syntax like [) is a nightmare for me. It even breaks other VSCode extensions I used that rely heavily on the balanced of brackets.

Thanks and regards!

pigpigyyy commented 1 year ago

@GokuHiki I got your point, the in range expr was removed and being replaced by chaining comparison operators. And list literal with [ ] is now available. You may also have a try now.

SkyyySi commented 1 year ago

I thought a bit about the square bracket list syntax, some ideas:

chrsm commented 1 year ago

Do you think list table syntax like arr = [] ...

I like the list table syntax of a = []. I think it makes sense given the append operation a[] = x. While Lua doesn't have a distinction it is nice to have an enforcement (even if you can, later, use a key on that table, just not in the decl).

chaining comparisons like 1 <= a <= 10 ...

Chained comparisons are fine. I'm a bit "old" so I tend to think of if ((x > min) and (x < max)) type things. But simplification is better (and less error-prone, too, considering accidental brain-swaps of symbols) - so it is also an improvement.

And what do you think about inline Lua codes syntax? Do you think just leaving it to the macro function is enough?

I didn't see this comment until now. The main reason I find the macro-to-Lua more useful is simply that the generated Lua can be modified programmatically.

I am not sure of the use case for mixing the two directly. Is there something that only Lua can do that Yue can't? If not, I'd just translate the Lua bits to Yue rather than mixing them. In the case of, say, a class, you'd need to know what the generated code looks like to reference generated things anyway, right? Which will likely be more annoying for those that use the feature.


@GokuHiki

And I use my custom Yue code highlight and some custom tools for Yue, because of that, maintaining it with syntax like [) is a nightmare for me. It even breaks other VSCode extensions I used that rely heavily on the balanced of brackets.

Is this highlight/tooling public? I only use the stock yue.vim and corresponding plugin when I've used vscode. I worked on a formatter a while ago but have not finished it.

GokuHiki commented 1 year ago

I use a very custom pipeline with the flow: a custom yue script -> transform to vanilla yue -> to lua code -> re-add only comment docs string, blank lines and reformat lua code + trackback yue line debug info -> lint lua code with luacheck + selene -> trackback problems to yue code and output errors to VSCode. I must use a custom syntax highlight solution because of it.

It is just a bundle of mismatched codes that combines many tools and scripts of some languages and relies heavily on regex as a dirty-quick solution for my specific requirements. I know it is not a good practice and easy to break when I write something that is out of normal but... at least, it works for now.

SkyyySi commented 1 year ago

@chrsm

I am not sure of the use case for mixing the two directly. Is there something that only Lua can do that Yue can't? If not, I'd just translate the Lua bits to Yue rather than mixing them. In the case of, say, a class, you'd need to know what the generated code looks like to reference generated things anyway, right? Which will likely be more annoying for those that use the feature.

The use case: Being lazy ;)

In terms of what you should do, either just rewrite it if it is small enough, or if not... it's probably already a library which you could just require/import it directly.