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 able to create a function with improper list arguments #948

Closed
jcubic opened this issue Jan 27, 2024 · 16 comments
Closed

Not able to create a function with improper list arguments #948

jcubic opened this issue Jan 27, 2024 · 16 comments

Comments

@jcubic
Copy link

jcubic commented Jan 27, 2024

Is this syntax supported:

(define (print x . rest)
  (apply display x rest)
  (newline))

This is like the fundamentals of lisp. I got an error like this:

WARNING: exception inside undefined operator: define
ERROR on line 5 of file syntax.scm: dotted list in source: (print x . rest)

When I try to use lambda:

(define print (lambda (x . rest)
                (apply display x rest)
                (newline)))

Got this error:

WARNING: exception inside undefined operator: lambda
WARNING: exception inside undefined operator: define
ERROR on line 5 of file syntax.scm: dotted list in source: (x . rest)
  called from on line 1292 of file /usr/share/chibi/init-7.scm
  called from on line 821 of file /usr/share/chibi/init-7.scm

Using chibi-scheme 0.10.0 "neon" from the official Fedora 39 package.

@ashinn
Copy link
Owner

ashinn commented Jan 27, 2024

You didn't import define, or any bindings at all, which is why you get

"WARNING: exception inside undefined operator: define"

Obviously if define is undefined then the expression is treated not as syntax but as a normal function application, where a dotted list is illegal syntax in pretty much every lisp.

Add '(import (scheme base))` to the top of your script to import define.

@ashinn ashinn closed this as completed Jan 27, 2024
@jcubic
Copy link
Author

jcubic commented Jan 27, 2024

I was not able to find this information in the documentation. Maybe I'm missing something but actually, I don't see any Scheme code in docs at all. I would add this as the first thing in the docs on how to use the system. If someone is new to Chibi they have no clue how to use it.

To add: none of the other Scheme implementations, that I was testing, work like this.

@mnieper
Copy link
Collaborator

mnieper commented Jan 27, 2024 via email

@lassik
Copy link
Contributor

lassik commented Jan 27, 2024

Correct me if I'm wrong, but Chibi expects a source file to be a "program" in R7RS terminology. R7RS section 5.1 says:

A Scheme program consists of one or more import declarations followed by a sequence of expressions and definitions.

This is not obvious and the error messages are confusing. A specification is not a good tutorial or manual.

@ashinn
Copy link
Owner

ashinn commented Jan 28, 2024

I had added the warning specifically for this case, thinking it was clear enough. Let me add a "Did you forget to import a language?" clause.

@jcubic
Copy link
Author

jcubic commented Jan 28, 2024

I would add information to the documentation on how to write cross-compatible code.

(cond-expand
 (chibi
  (import (scheme base)
          (chibi)))
 (else))

Only Chibi is required to import something to do anything.

@mnieper
Copy link
Collaborator

mnieper commented Jan 28, 2024

I would add information to the documentation on how to write cross-compatible code.

(cond-expand
 (chibi
  (import (scheme base)
          (chibi)))
 (else))

Only Chibi is required to import something to do anything.

Any conforming implementation of R7RS programs (see section 5.1 in the R7RS) starts with an empty environment unless something is imported. From the cited section: "The initial environment of a program is empty, so at least one import declaration is needed to introduce initial bindings."

This is different to REPL semantics (see section 5.7). Here, the standard says: "For convenience and ease of use, the
global Scheme environment in a REPL must not be empty, but must start out with at least the bindings provided by the base library."

Chibi implements both conforming programs and a conforming REPL.

@jcubic
Copy link
Author

jcubic commented Jan 28, 2024

Does it mean that only Chibi is a real R7RS compilat Scheme Implementation?

Anyway, this should be in the documentation, since no other Scheme I've tested works like this, so it's at least confusing (especially to newcomers).

I would add a section like this:

R7RS Scheme Conformance

Because the Chibi Scheme is fully compatible with R7RS it requires at least of import of base module to work.

e.g.:

(import (scheme base))

@lassik
Copy link
Contributor

lassik commented Jan 28, 2024

(cond-expand
 (chibi
  (import (scheme base)
          (chibi)))
 (else))

A cond-expand is not necessary if you are targeting R7RS implementations.

(import (scheme base)) works in all of them. (Try it!)

(import (chibi)) is not needed to run portable programs in Chibi.

@lassik
Copy link
Contributor

lassik commented Jan 28, 2024

Does it mean that only Chibi is a real R7RS [compliant] Scheme Implementation?

It does not mean that.

The issue is confusing because "program" is a common word, but R7RS uses the word "program" in its own exact sense.

R7RS says how its "programs" behave. But RnRS does not cover the command line usage of Scheme implementations. So it does not dictate that chibi-scheme foo.scm or lips foo.scm should interpret foo.scm as an R7RS program. The implementation is free to interpret foo.scm as something else.

Anyway, this should be in the documentation, since no other Scheme I've tested works like this, so it's at least confusing (especially to newcomers).

+1

@lassik
Copy link
Contributor

lassik commented Jan 28, 2024

Historically, (import ...) was added to Scheme quite late, in R6RS and R7RS. import was not a part of R5RS. That's probably the reason why many Scheme implementations import a lot of stuff by default.

@mnieper
Copy link
Collaborator

mnieper commented Jan 28, 2024 via email

@lassik
Copy link
Contributor

lassik commented Jan 28, 2024

Gauche at least detects a source file that starts with (import ...) and switches to R7RS mode. If the file starts with something else, it stays in its traditional mode. This is slightly confusing, but works well once you know it.

@ashinn
Copy link
Owner

ashinn commented Jan 28, 2024

The Chibi docs are very explicit about being a native R7RS implementation. All examples, scripts and tests in the distribution begin with an import (as does the sample program in the R7RS spec). I can add an extra note to the docs, but it's more important to make the error message clearer for people who don't read the docs.

As Marc points out, the reason R7RS chose not to provide a default language in programs is explicit control of bindings, to avoid import conflicts and in particular for clean macro semantics.

However as noted above, the Chibi repl does provide a (run-time configurable) default language and you can always load the script in repl mode with chibi-scheme < foo.scm (or with the -l option).

Note the (cond-expand ...) suggestion is pointless because it's not needed for R7RS implementations, and if you abandon even R7RS compatibility it's impractical to write useful programs.

@ashinn
Copy link
Owner

ashinn commented Jan 30, 2024

Updated the docs as described and added a new warning, hopefully this is clear enough:

WARNING: exception inside undefined operator: define
WARNING: did you forget to import a language? e.g. (import (scheme base))
ERROR on line 4 of file foo.scm: dotted list in source: (print x . rest)
  called from <anonymous> on line 1268 of file ./lib/init-7.scm
  called from <anonymous> on line 800 of file ./lib/init-7.scm

@lassik
Copy link
Contributor

lassik commented Jan 30, 2024

Excellent. Thank you.

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

4 participants