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

Script to redeploy testlib.sml to all exercises on changes. #206

Merged
merged 11 commits into from
Jun 20, 2022
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ test-%:
@cd ./exercises/practice/$(exercise) && cat test.sml | sed 's/$(exercise).sml/.meta\/example.sml/' | poly -q
@echo

.PHONY: test
redeploy-testlib:
poly --script sml-bin/redeploy-testlib.sml

.PHONY: test redeploy-testlib
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ Every exercise must have at least these files:

### `testlib.sml`

This helper has this structures:
The copy of `testlib.sml` for each exercise should be in sync with `lib/testlib.sml`.
`make redeploy-testlib` is provided for syncing all exercises with `lib/testlib.sml`
guygastineau marked this conversation as resolved.
Show resolved Hide resolved
when it is updated.

This helper has these structures:

```sml
structure Expect:
Expand Down
50 changes: 50 additions & 0 deletions sml-bin/redeploy-testlib.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
structure Path = OS.Path
structure File = OS.FileSys

fun printLn x = print (x ^ "\n")

fun fileExists x = File.access (x,[])

fun testLibName base slug =
Path.joinDirFile
{
dir = (Path.concat (base,slug)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space in dir = (Path.concat (base,slug)),.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What space? I don't have a space between x and [] in line 6, File.access (x,[]).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe for consistency with testlib one could write f(x, y) instead of f(x,y) everywhere. But think it is not important. Consistency can also be a pain :D.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after comma,after all,is helpful in reading,so they say. I do not know why,in any instance,one would not use a space,every time,after a comma.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got used to it, because a lot of old SML doesn't use spaces in tuples. Of course, a lot of old SML tries to immitate c-style function calls by excluding a space between uncurried function names and their product argument; this convention really annoys me, so I don't need to stick with the other convention for a partial tradition either. I will change it if you all think it is better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is the difference of my eyes seeing the comma, and not seeing it. So white space in code, when not syntactically limited to white space breaking things when there can definitely benefit from having it.

file = "testlib.sml"
}

fun dirList dirname =
let
fun go d xs =
case File.readDir d of
SOME x => go d (x::xs)
| NONE => (File.closeDir d; xs)
in
go (File.openDir dirname) []
end

fun fileBytes path =
let
val in' = BinIO.openIn path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it some well-established convention to call this in'? Looks a little bit awkward to me, especially since my IDE (vscode) and even github recognize the first two characters as a keyword. Would you mind calling it differently?

Actually I have checked that my emacs with SML mode does not have this issue, but even there I would prefer not to call it in'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered changing it in case it is confusing, but using ' as a prime like identifier modification is pretty common in the ML family. For the record, I think the fact of general tooling being incapable of recognizing/capturing the expressiveness of a language is a poor reason to limit one's expressiveness when using the language. If I rename it I am likely to name it ins which was a close second in my consideration. I suppose instream isn't too long though. I don't know why I felt so averse to a longer name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that bad tooling is not the best reason for a change, but this was just for information. I have nothing against prime in general but here it seems to be there only because using in is not legal and I feel this is no good reason either. Most of the time when I encountered a "primed" variable, then there also was a related variable without a prime.

My question about conventions was more specifically about using the exact string in' as a whole (not just something with a prime at the end).

So if you already considered it to be confusing why not change it to ins (wouldn't be my choice, but I would be fine with it)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right. Prime here is not really really semantically consistent, but rather it is a syntactic hack to get around not having my ideal identifier. Sorry, I meant to make my last comment sound more positive about changing the name of the declaration. Oat likely I will call it instream or inStream. I am at work right now, so I won't get to it until later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The longer name of instream would be preferable to any of the shorter names. You could still use the ' to indicate the additional information stated @guygastineau .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @kotp. Yes, you are right about instream. I have pushed it now. ' didn't have any meaning in my usage which is why it was wrong. I was using a more or less semantic naming convention as a hack to get around the inconvenience of a keyword.

val bytes = BinIO.inputAll in'
in
BinIO.closeIn in'; bytes
end

fun writeFileBytes bytes path =
let
val out = BinIO.openOut path
in
BinIO.output (out, bytes);
BinIO.closeOut out
end

fun relUnixPathToAbs x= Path.concat ((File.getDir ()), Path.fromUnixPath x)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space in fun relUnixPathToAbs x= .


val _ =
let
val concept = relUnixPathToAbs "exercise/concept"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concept is unused, so I would delete it.

val practice = relUnixPathToAbs"exercises/practice"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space in relUnixPathToAbs"exercises/practice".

val testLib = fileBytes "lib/testlib.sml"
in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind writing List.app instead of app? I am usually explicit with these things (because I hate puzzling out what this is if I come back after some time of absence from some particular topic like SML). But it is a question, so feel free to stay with app.

app (writeFileBytes testLib o testLibName practice) (dirList practice)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a very short docstring explaining what the script does might be a good idea (maybe at the top of the file). Of course the filename essentially says it but I would still prefer a short docstring. Let me know if you think this would not be helpful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment basically restating the name of the script seems pretty redundant to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I am fine with that, I was just a little bit worried if somebody else might wonder what exactly "redeploy" might mean.

Copy link
Contributor Author

@guygastineau guygastineau Jun 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I often take for granted that English is my first language, aber meine Meinung nach sollen wir die Problemen sprachlicher Mehrdeutigkeit der Nicht-Muttersprachlichern beachten 🙃

So, maybe it is best for there to be some more direct comments in the script 😄

end