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

Lisp Koans 2.0 #111

Merged
merged 58 commits into from
May 9, 2020
Merged

Lisp Koans 2.0 #111

merged 58 commits into from
May 9, 2020

Conversation

phoe
Copy link
Contributor

@phoe phoe commented May 9, 2020

What

This PR completely overhauls the Lisp Koans in an attempt to make them better in every way the author of the PR can imagine.

How

  • We refactor the testing and printing frameworks and shave about 660 lines off its size in result.
    • We highly customize the attached lisp-unit test framework and gut out everything that is not required to work with the koans. A side effect is that verifying the koans should now be slightly faster.
    • We refactor the file contemplate.lsp into two files: lisp-koans.lsp that defines the package and functions related to koans and contemplate.lsp which actually loads the code and executes the main function.
  • We rewrite all the existing koans.
    • We bring koans to modern and unified Lisp coding style.
    • We fix tests that depend on implementation-defined or undefined behaviour.
    • We change the order of several lessons to better suit inter-lesson dependencies.
    • We add several new koans and lessons.
  • We add a test suite by means of attaching a solution set for all koans and including a command for running those.

Why

  • The much smaller code of the testing and printing framework is more readable and maintainable due to dead code removal.
  • The above will allow lisp-koans to be loadable via ASDF in the future, and it will be possible to evaluate koans' completion via the Lisp REPL instead of using shell scripts.
  • This PR will also allow to include lisp-koans in Quicklisp in the future. The internal package lisp-unit was renamed and therefore no longer collides with the Quicklisp-providable lisp-unit system.
  • The comment styles in previous koans was highly inconsistent; it treated strings as comments and also disrespected the standard advice on semicolon usage,
  • The previous koans sometimes seemed as if they were translated straight from Python and/or Ruby ones, not taking into account Lisp idioms, features, or coding styles.
  • The previous koans often depended on implementation-defined or undefined behaviour, which are bugs.

What not

Quicklisp/ASDF integration will come later.

What else

  • code review

The real fun stuff begins here

phoe added 30 commits May 5, 2020 12:51
DEFCONSTANT is signaling an error when lisp-unit.lisp is reloaded. The
simplest fix is to change the form to DEFVAR instead.
In order to put the koans on Quicklisp, we need to ensure that the version of
lisp-unit bundled with the koans does not clash with the Quicklisp-distributed
version of lisp-unit. Therefore, we rename the package.
Create a MAIN function and execute it instead of having bare toplevel forms.
Comments have been adjusted to follow CLHS standards.
All #||#-style comments have been replaced with semicolon ones.
Superfluous newlines have been removed.
The tag-functionality was present, but completely unused. For code clarity,
it is now removed.
It should be possible to infer load-time errors with backtraces alone.
@Slids
Copy link
Collaborator

Slids commented May 9, 2020

Your packages should generally pertain to the package it's using.
Do you expect anyone else to use lisp-koans.foo anywhere else?
What does using net.common-lisp add?
Having it backed up somewhere else is perfectly fine, it's probably beneficial to have it on common-lisp.net.

@Slids
Copy link
Collaborator

Slids commented May 9, 2020

I also work on cl-protobufs.
If you make a proto

optional (lisp_package) = "foo"; 
mesasge bar { 
  optional integer quux = 1;
}

it will create a package
cl-protobufs/foo containing structure
cl-protobufs/foo:bar.

We've been debating the existence of cl-protobufs/ as a pre-pended thing.
It makes the package name larger and seemingly comes out of nowhere.
Another person thinks it gives a nice division and removes package collisions.

@goranmoomin
Copy link

Well, at least for me, I consider the name lisp-koans to be a bit generic (since it's a name that someone else which doesn't know the presence of this project can think of). I think it would be beneficial to have a FQDN for this purpose, but it's a matter of taste though.

@Slids
Copy link
Collaborator

Slids commented May 9, 2020

Then probably qitab
That should be the fqdn for lisp code from google.
If I were to release this code today it would be in the
https://github.com/qitab
and if it goes to common-lisp.net it should go to qitab.
I'd suggest none, but I would be okay with that.
Also:
https://common-lisp.net/project/qitab/

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

It makes the package name larger and seemingly comes out of nowhere.

That's where package-local nicknames come in: in the scope of your package, you can nickname cl-protobuf/foo:bar to just foo:bar or f:bar, depending on your taste.

I'll just go with lisp-koans.{test,core,koan-foo,koan-bar,...}.

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

Done. What's the next step?

@Slids
Copy link
Collaborator

Slids commented May 9, 2020

That's a good point, but it's not in the standard :/

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

@Slids Neither are sockets, threads, MOP, or accessing the garbage collector. There are portability libraries for all of them, and PLNs are no exception - see https://github.com/phoe/trivial-package-local-nicknames

Currently PLNs are supported by SBCL, CCL, ECL, Clasp, ABCL, LispWorks and ACL. Only CLISP is missing out, but I plan on fixing it someday.

@Slids
Copy link
Collaborator

Slids commented May 9, 2020 via email

@Slids
Copy link
Collaborator

Slids commented May 9, 2020 via email

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

Everyone implementing package-local nicknames also implements them the same way by using the :local-nicknames extension to :defpackage and four functions: package-local-nicknames, package-locally-nicknamed-by-list, add-package-local-nickname, and remove-package-local-nickname. I guess that sharing the same API counts as an implementation that everyone agrees on.

All that the portability library does is grabbing the symbols for these functions from implementation-defined packages and reexporting them. In fact, I can paste the whole code of that library here:

(defpackage #:trivial-package-local-nicknames
  (:use #:cl)
  (:import-from
   #+sbcl #:sb-ext #+ccl #:ccl #+ecl #:ext #+abcl #:ext
   #+clasp #:ext #+lispworks #:hcl #+allegro #:excl
   #:package-local-nicknames
   #:package-locally-nicknamed-by-list
   #:add-package-local-nickname
   #:remove-package-local-nickname)
  (:export
   #:package-local-nicknames
   #:package-locally-nicknamed-by-list
   #:add-package-local-nickname
   #:remove-package-local-nickname))

@Slids
Copy link
Collaborator

Slids commented May 9, 2020 via email

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

OK - we're going offtopic anyway. :)

@Slids Slids merged commit 9f4aa74 into google:master May 9, 2020
@Slids
Copy link
Collaborator

Slids commented May 9, 2020

Well, that was a huge change!

@Slids
Copy link
Collaborator

Slids commented May 9, 2020

Thank you!

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

Thanks a million!

I'll keep an eye on the repository in case there are any bugs remaining after the change.

@Slids
Copy link
Collaborator

Slids commented May 9, 2020 via email

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

The lisp spec really should be updated.

By whom? That's the biggest question for me. X3J13 has disassembled after successfully creating a standard named ANSI CL, and I don't know how many of its members would still like to do a take-two after almost thirty years. Then there's the question of adopting the new specification, which is even more of a question.

@Slids
Copy link
Collaborator

Slids commented May 9, 2020 via email

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

There's tons of work with maintaining and developing SBCL as an ANSI CL implementation that, I suppose, is going to keep them busy - I have no idea if any of them would spend the time on extra credit work of drafting, testing, discussing, debating, approving, and implementing a new language specification.

Plus, I don't know if any of them want a new CL specification - the old one is surprisingly good enough for many many uses. We also have the current de facto standards established by portability libraries, which also are good enough for many use cases.

@Hexstream
Copy link

Hexstream commented May 9, 2020

Since the CLHS cannot be updated, I think a modern public domain spiritual successor to the CLHS based on dpANS3 would be the first and necessary logical step to modernizing and updating the standard.

I wish I could work on this like what I did for the MOP specification, but my infrastructure is not quite there yet...

@Slids
Copy link
Collaborator

Slids commented May 9, 2020 via email

@phoe
Copy link
Contributor Author

phoe commented May 9, 2020

@bileschi
Copy link
Member

Very nice!

@Slids
Copy link
Collaborator

Slids commented May 10, 2020 via email

stewart123579 added a commit to stewart123579/lisp-koans that referenced this pull request Dec 23, 2021
bordeaux-threads doesn't have count of threads functionality.

See:
    sionescu/bordeaux-threads#70
    google#111
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment