aya-lang / aya

Pocket sized programs
MIT License
54 stars 3 forks source link

Wiki Correctness #67

Closed BlazingTwist closed 1 year ago

BlazingTwist commented 2 years ago

I have found this project recently and really quite like it, but I have a few gripes with the wiki.

Range Operator 'R'

https://github.com/aya-lang/aya/wiki/Lists#generators Seems outdated 'dR starts listing characters from what I assume to be either char-code 0 or 1

Also Three items: create a range from the first to the third using the second as a step. could use rephrasing (or an example that doesn't start at 0) in my opinion, because I expected [2 0.5 4]R .# -> [2 2.5 3 3.5 4] (with the second number being the distance between each element). But the Operators page confirms that the second number is supposed to be the second number in the generated range [2 2.5 4]R .# -> [2 2.5 3 3.5 4]

Min/Max Operators .> and .<

https://github.com/aya-lang/aya/wiki/Operators states .> returns the greater of two numbers | and .< returns the lesser of two numbers I think symbolically 5 9 .> .# -> 5 makes sense, reading it as "narrowing" of a range, so only the description has to be changed.

Also, I think [5 3 9] .> .# -> 3 and "bac".> .# -> 'a (minimum and maximum of a list / string) would be an intuitive addition. Since the head/tail operator requires a normal number on top of the stack, this would integrate without collisions.

Increment/Decrement Operators B and V

https://github.com/aya-lang/aya/wiki/Operators for V states N|C: increment, but V performs a decrement.

also B and V state that they inc/dec in-place. What does that mean? I would expect after doing 5:a; aV the value of a would be 4, but it's still 5

Index Operator .I

https://github.com/aya-lang/aya/wiki/Operators states LN|LL: index, keep list on stack So I'd expect [2 1 0] 2 .I .# -> [2 1 0] 0, but the actual output is unexpected empty stack It seems the actual implementation is LNA|LLA: <list><index><default> : get list at index, or default if index out of bounds

I prefer that implementation (keep list on stack can be done with $ in just as many characters anyway), but the documentation needs to be updated.

Index-Of Operator N and .N

Currently both of these Operators keep the list on the stack (which is sometimes useful, other times not) but https://github.com/aya-lang/aya/wiki/Operators does not state that this is the case.

nick-paul commented 2 years ago

I'm glad you have been enjoying the project! Thanks for the detailed notes on the errors in the wiki. I made some updates to address them in 525e94d55bfda8eec1402802163bbcb94c8e1a18 (more details below). I've realized that wiki is a bit out of date overall so I'll review it over the next few days to see if I can correct any other errors.

Range Operator R

'dR starts listing characters from what I assume to be either char-code 0 or 1

This was changed to match the functionality of numerals ('d R now has the same result as 'd :" R ." where :": char(s) to int(s), ." int(s) to char(s))

"ad" R Can be used to get the old functionality but if you are golfing, it does cost more chars. Could possibly define .r for chars to get the old result but with only 1 more char:

aya> {$.islower 'a 'A .? JCR} 'x.M.:r;
aya> 'd.r
"abcd" 
aya> 'D.r
"ABCD" 

Min/Max Operators

states .> returns the greater of two numbers | and .< returns the lesser of two numbers

Good catch, updated the wiki and kept the behavior the same

Also, I think [5 3 9] .> .# -> 3 and "bac".> .# -> 'a (minimum and maximum of a list / string) would be an intuitive addition.

Every operator has a fixed number of arguments it takes*. In the case of .</.< it's 2. [5 3 9] .> provides only a single argument so a different operator would need to be used. Currently, there are a few ways to git the min/max of a list, just not with a single operator:

Using .> and the fold operator (/):

aya> [5 3 9] {.>} /
3 
aya> [5 3 9] `.> / .# `x is shorthand for {x}
3 

Or using the standard library functions .min/.max:

aya> [5 3 9].min
3

*There are a few exceptions to this rule for operators that operate on the entire stack. For example .A wraps the entire stack up as a list so the number of arguments is equal to however many are currently on the stack. These are denoted with .. on the operators page.

Increment/Decrement Operators B and V

for V states N|C: increment, but V performs a decrement.

Updated the docs

also B and V state that they inc/dec in-place. What does that mean?

Pass the variable as a symbol (Symbol type abbreviated as J on the wiki) to increment/decrement in-place:

aya> 1 :a
1 
aya> ::a B
aya> a
2 

Index Operator .I

https://github.com/aya-lang/aya/wiki/Operators states LN|LL: index, keep list on stack

The behavior of this operator was changed. I updated the docs to reflect the change

Index-Of Operator N and .N

Currently both of these Operators keep the list on the stack (which is sometimes useful, other times not) but https://github.com/aya-lang/aya/wiki/Operators does not state that this is the case.

Added additional details to the wiki.

I have considered changing these to not keep the list on the stack as I find myself not needing the list more often than not. (N\; appears 20 times in the examples and standard library). Perhaps the "don't keep the list" version can be split into another operator.

BlazingTwist commented 2 years ago

Thanks for the exhaustive reply! It seems I should dig around more in the standard libraries.

Speaking of standard libraries, whenever I try to do import ::io the apps CPU usage spikes to 30% and ram usage continuously crawls up. Have waited until it ate 6 GB of ram, but it doesn't seem to become responsive afterwards again.

Also, `x is shorthand for {x} caught me off guard. I've scrolled a bit, but can't seem to find that in the wiki. What I did find is https://github.com/aya-lang/aya/wiki/Ticks-and-Groups#ticks which seems to not be a thing anymore. Most of the use cases can probably be substituted with the existing stack operators, but defining custom infix operators seems tricky.

Symbols are also somewhat hard to grasp for me. I've seen :: a few times, but I'm not sure when to use it. I guess I have missed the memo that :: means "treat whatever characters come next as a symbol" ?

While digging through __aya__.aya I have found .` which I can't find on the Operators page. From testing, it seems to return the definition of a variable?

nick-paul commented 2 years ago

whenever I try to do import ::io the apps CPU usage spikes to 30% and ram usage continuously crawls up

Odd, I don't think I've had this issue before. What platform are you on? Are you using a release or building from source?

Also, `x is shorthand for {x} caught me off guard. I've scrolled a bit, but can't seem to find that in the wiki.

The behavior of ` was changed somewhat recently the wiki has not been updated to reflect the change yet. I added a basic description of the current behavior here.

Symbols are also somewhat hard to grasp for me ... I guess I have missed the memo that :: means "treat whatever characters come next as a symbol"

Symbols are similar to Ruby's symbols. They are mostly used as a kind of "enum" or for metaprogramming. I'll plan to add more details on them in #68

Here's the syntax overview for them in the meantime: Symbols

While digging through aya.aya I have found .` which I can't find on the Operators page

Added to the syntax overview here

Also, __aya__.aya is a pretty complicated file since it is the entry-point for the standard library and defines a bunch of keywords using some of the language's metaprogramming features. The examples directory has some "friendlier" programs until I get the wiki up to date with the more advanced features.

BlazingTwist commented 2 years ago

Odd, I don't think I've had this issue before. What platform are you on? Are you using a release or building from source?

Initially I've looked at the releases, but the most recent one seems quite old. So I've built 2 artifacts with AyaIDE and InteractiveAya as their main classes. Built for this commit I'm using "Windows 10 Pro", Version "21H1", OS build "19043.1415"

On an unrelated note (stop me, if this is too off-topic) I'm not entirely happy with how N/.N and .I interact with each other. N returning "-1 if not found" does make sense since indices usually range from 0 to n. But since Aya supports negative indices, ["1" "2" "3"] "4" N "not found" .I will return "3" so you have to handle the -1 somehow. On the spot, the best thing I can come up with is ["1" "2" "3"] "4" N $0<{;3}? "not found" .I which seems rather clunky. (where 3 would have to be some index that is guaranteed to be out of bounds)

nick-paul commented 2 years ago

Just tested in windows and had some problems with importing due to file encodings and different path separator.

Both are fixed in c20a2f9e8c644a66d5721af2000efa45de08a6d6 and I was able to import the full standard library and run all tests (load "test/test") with no errors. My CPU maxed out around 10% and memory stayed below 1GB. Can you see if those fixes work for you?

Regarding Ns not-found behavior: these are great points, opened a separate issue here: #69

BlazingTwist commented 2 years ago

The import issue is still happening on my end.

I've done a bit of digging through the importlib, the last log I get is "Attempting to open file $filename..." Doing "<aya>\\std\\io.aya" G seems to work correctly, but "<aya>\\std\\io.aya" G ~ freezes with no further output.

Done even more digging and found the culprit:

.#? path.root\n  root dir name
iswindows {
    "C:"
} {
    ""
} .? path.:root;

"C:" won't work, since I'm running Aya on my "D:" drive.

For path::_isabs you can probably just check for the presence of : on windows, since : is not allowed for directory names. (that might collide with file URIs, but I suppose file://hostname/path is technically an absolute path as well)

In path::_clean I'm pretty sure dirs [path.root "."] :| ; doesn't do anything?

That just leaves path::__str__ which might be tricky to fix for files on different drives.

nick-paul commented 2 years ago

Gah, probably shouldn't have hard-coded the drive. Should be fixed in e0042201cedd7c3fe003a49ee099ec5073124a18. I also fixed the path::_clean bug in 1107bf91a10cd09cffdc74d7ee446cf14854bad3.

BlazingTwist commented 2 years ago

Cool, cool, but I'm experiencing 2 issues:

Considering that the fstream.O instruction is called LegacyFStreamInstruction internally, I have to wonder: should I even use the io library? The G operator seems to work well with windows.

Also, while browsing the changes I also noticed that the OP_Bar and OP_Tilde operators are not on the Operators page.

nick-paul commented 1 year ago

I know this is a super old issue but I wanted to resolve it before 0.4

I modified the path implementation so it no longer automatically attempts to resolve or clean anything in the constructor. You can still run the old resolve and clean functions manually if needed. Can you test if that fixes the issue on windows?

If there are still issues, I recommend we close this issue and open a more specific one to address them directly.

Also I added OP_Bar and OP_Tilde to the documentation.

The changes are on the 0.4-dev branch

BlazingTwist commented 1 year ago

I wish I had been a bit more clear on what I did exactly, because I sure don't remember anymore. So I tried some basics: