Re: [PATCH] add language/wisp to Guile?

2023-02-04 Thread Dr. Arne Babenhauserheide

Maxime Devos  writes:

>> This needs an addition to the extensions via guile -x .w — I wrote
>> that
>> in the documentation. I didn’t want to do that unconditionally, because
>> detecting a wisp file as scheme import would cause errors.
>
> If done carefully, I don't think this situations would happen.
> More precisely:
>
>   * .w would be in the file extensions list.
>
>   * Instead of a list, it would actually be a map from extensions to
> languages:
>
>   .scm -> scheme
>   .w -> wisp
>
> With this change, (use-modules (foo)) will load 'foo.scm' as Scheme
> and 'foo.w' as Wisp.  (Assuming that foo.go is out-of-date or
> doesn't exist.)
>
> (For backwards compatibility, I think %load-extensions needs to
> remain a list of strings, but a %extension-language variable could
> be defined.)
>
>   * "guile --language=whatever foo" loads foo as whatever, regardless
> of the extension of 'foo' (if a specific language is requested,
> then the user knows best).
>
>   * "guile foo" without --language will look up the extension of foo in
> the extension map. If an entry exists, it would use the
> corresponding language.  If no entry exists, it would use
> a default language (scheme).

This sounds good, though a bit more complex than I think it should be.

I think this should stick to only load Scheme if no language is detected
to keep Scheme the default language for Guile — and also to avoid
stumbling over files that just take that extension. Checking more files
could slow down startup and I think having multiple languages fully
equal would risk splintering the development community.

Guile is first and foremost Scheme and fast startup time is essential.

More complicated is what should be done if a *.go file is detected
during import. There I could see Guile check if a file with any
supported extension is up to date.

>> Is there a way to only extend the loading mechanism to detect .w when
>> language is changed to wisp?

> I don't care what language the library Foo is written in, and my
> library Bar isn't written in Wisp so it seems unreasonable to have to
> add -x w.

I think you’re right with that. For any already compiled library, the
language should not matter.

>> readable uses
>
> This sentence appears to be incomplete; I might have misinterpreted it
> below (I don't know what you mean with 'readable' -- its an adjective
> and you are using it as a noun?).

readable is a noun, yes: the readable lisp project.

>> (set! %load-extensions (cons ".sscm" %load-extensions))
>> Would that be the correct way of doing this?

> FWIW, it appears to be an answer to the following unasked question:
>
>   How to make Guile accept "foo.go" when "foo.w" exists and is
>   up-to-date.

Yes, I think that is the most important question. If that is solved,
guile provides a multi-language environment in which only the build
tools of the libraries themselves have to know the languages used.

> This sounds like the second proposal ('alternatively ...'), but the
> way it is written, you appear to proposing it as a third proposal.  Is
> this the case?

It only differs in details (keeping Scheme more central and only
checking for non-scheme languages if a *.go file is detected).

> (I mean, after this patch, Wisp is a supported language, so it seems
> equivalent to me.)

Pretty close, yes.

 +; Set locale to something which supports unicode. Required to avoid
 using fluids.
 +(catch #t
>>>
>>>   * Why avoid fluids?
>> I’m not sure anymore. It has been years since I wrote that code …
>> I think it was because I did not understand what that would mean for
>> the
>> program. And I actually still don’t know …
>> Hoow would I do that instead with fluids?
>> 
>>>   * Assuming for sake of argument that fluids are to be avoided,
>>> what is the point of setting the locale to something supporting
>>> Unicode?
>> I had problems with reading unicode symbols. Things like
>> define (Σ . args) : apply + args
>> [...]>
>> This is to ensure that Wisp are always read as Unicode. Since it uses
>> regular (read) as part of parsing, it must affect (read), too.
>
> OK.  So, Wisp files are supposed to be UTF-8, no matter the locale?
> AFAICT, the SRFI-119 document does not mention this UTF-8 (or UTF-16,
> or ...) requirement anywhere, this seems like an omission in
>  to me.

That’s an omission, yes … but since it was omitted (by me …), you’re
right. Forcing UTF-8 is actually not the way.

> First, I would like to point out the following part of
> ‘(guile)The Top of a Script File’:
>
>• If this source code file is not ASCII or ISO-8859-1 encoded, a
>  coding declaration such as ‘coding: utf-8’ should appear in a
>  comment somewhere in the first five lines of the file: see *note
>  Character Encoding of Source Files::.
…
> (OTOH, (guile)Character Encoding says 'In the absence of any hints,
> UTF-8 is assumed.' 

Re: [PATCH] add language/wisp to Guile?

2023-02-04 Thread Maxime Devos



On 04-02-2023 16:46, Dr. Arne Babenhauserheide wrote:

[...]

So I’d like to ask: can we merge Wisp as supported language into Guile?


 From some conversations elsewhere, I got the impression that

(use-modules (foo))

will search for foo.scm and not in foo.w.  I think you'll need to
tweak the loading mechanism to also look for foo.w instead of only
foo.scm, if not done already.


This needs an addition to the extensions via guile -x .w — I wrote that
in the documentation. I didn’t want to do that unconditionally, because
detecting a wisp file as scheme import would cause errors.


If done carefully, I don't think this situations would happen.
More precisely:

  * .w would be in the file extensions list.

  * Instead of a list, it would actually be a map from extensions to
languages:

  .scm -> scheme
  .w -> wisp

With this change, (use-modules (foo)) will load 'foo.scm' as Scheme
and 'foo.w' as Wisp.  (Assuming that foo.go is out-of-date or
doesn't exist.)

(For backwards compatibility, I think %load-extensions needs to
remain a list of strings, but a %extension-language variable could
be defined.)

  * "guile --language=whatever foo" loads foo as whatever, regardless
of the extension of 'foo' (if a specific language is requested,
then the user knows best).

  * "guile foo" without --language will look up the extension of foo in
the extension map. If an entry exists, it would use the
corresponding language.  If no entry exists, it would use
a default language (scheme).

With these changes, I don't think that Wisp code would be detected as 
Scheme or the other way around.



Is there a way to only extend the loading mechanism to detect .w when
language is changed to wisp?


Regardless of whether it's technically possible, that sounds 
insufficient to me.


Suppose someone writes a library 'Foo' in Wisp.
Suppose I write a library 'Bar' in parenthese-y Scheme, that happens to 
use the Foo library as a dependency.


Then when compiling Bar or running its tests, it will be done in the 
Scheme language, and additionally assuming that compiled .go are 
available for Foo, then the language will never be changed to Wisp, and 
hence .w will never be added to %load-extensions.


As such, the Makefile.am or equivalent of Foo would need to be converted 
to Wisp, or '-x w' would need to be added.


I don't care what language the library Foo is written in, and my library 
Bar isn't written in Wisp so it seems unreasonable to have to add -x w. 
(It wouldn't be too much trouble, but still not something that should 
have to be done _in Bar_, as the Wispyness of Foo is just an 
implementation detail of Foo, not Bar.)


Worse, adding the Wispy library Foo of the parenthese-y library Bar 
would be an incompatible change, as parenthese-y dependents of Foo would 
need to add '-x w' in places whereas they didn't to previously.  It's 
easily resolvable, but I think it would be very annoying as well.



readable uses


This sentence appears to be incomplete; I might have misinterpreted it 
below (I don't know what you mean with 'readable' -- its an adjective 
and you are using it as a noun?).



(set! %load-extensions (cons ".sscm" %load-extensions))

Would that be the correct way of doing this?


I assume you meant ".w" instead of ".sscm".  I don't quite see how this 
would be an answer to:


  Is there a way to only extend the loading mechanism to detect .w when
  language is changed to wisp?

More precisely, I'm missing how it addresses 'only ... when the language 
is changed to wisp'.


FWIW, it appears to be an answer to the following unasked question:

  How to make Guile accept "foo.go" when "foo.w" exists and is
  up-to-date.


Also, I think that when foo.go exists, but foo.scm doesn't, then Guile
refuses to load foo.scm, though I'm less sure of that. If this is the
case, I propose removing the requirement that the source code is
available, or alternatively keep the 'source code available'
requirement and also accept 'foo.w', if not done already.


I think accepting any extension supported by any language in Guile would
be better.


This sounds like the second proposal ('alternatively ...'), but the way 
it is written, you appear to proposing it as a third proposal.  Is this 
the case?


(I mean, after this patch, Wisp is a supported language, so it seems 
equivalent to me.)



+; Set locale to something which supports unicode. Required to avoid
using fluids.
+(catch #t


  * Why avoid fluids?


I’m not sure anymore. It has been years since I wrote that code …

I think it was because I did not understand what that would mean for the
program. And I actually still don’t know …

Hoow would I do that instead with fluids?


  * Assuming for sake of argument that fluids are to be avoided,
what is the point of setting the locale to something supporting
Unicode?


I had problems with reading unicode symbols. Things like
define (Σ . args) : apply + args

> [...]>

Re: [PATCH] add language/wisp to Guile?

2023-02-04 Thread Dr. Arne Babenhauserheide
Thank you for your review!

Maxime Devos  writes:

>> Why add Wisp?
>> For Wisp: it is then available directly wherever Guile is available.
>>   This will make it much easier for people to follow tutorials.
>
> I'm not convinced of this argument, because package managers exist, but ...
>
>> For Guile:
>> - Wisp has proven to be good at enabling people to get an
>>   entrance to Scheme² without pulling them out of the community.
>> - [...]
>
> ... all good points, and the implementation of Wisp is tiny anyway.
> For an additional reason: Wisp is a SRFI (Scheme Requests for
> Implementation) and Guile is a Scheme implementation.

That’s a good point — I should really have written it :-)

>> So I’d like to ask: can we merge Wisp as supported language into Guile?
>
> From some conversations elsewhere, I got the impression that
>
> (use-modules (foo))
>
> will search for foo.scm and not in foo.w.  I think you'll need to
> tweak the loading mechanism to also look for foo.w instead of only
> foo.scm, if not done already.

This needs an addition to the extensions via guile -x .w — I wrote that
in the documentation. I didn’t want to do that unconditionally, because
detecting a wisp file as scheme import would cause errors.

Is there a way to only extend the loading mechanism to detect .w when
language is changed to wisp?

readable uses

(set! %load-extensions (cons ".sscm" %load-extensions))

Would that be the correct way of doing this?

> Also, I think that when foo.go exists, but foo.scm doesn't, then Guile
> refuses to load foo.scm, though I'm less sure of that. If this is the
> case, I propose removing the requirement that the source code is
> available, or alternatively keep the 'source code available'
> requirement and also accept 'foo.w', if not done already.

I think accepting any extension supported by any language in Guile would
be better.

>> +; Set locale to something which supports unicode. Required to avoid
>> using fluids.
>> +(catch #t
>
>  * Why avoid fluids?

I’m not sure anymore. It has been years since I wrote that code …

I think it was because I did not understand what that would mean for the
program. And I actually still don’t know …

Hoow would I do that instead with fluids?

>  * Assuming for sake of argument that fluids are to be avoided,
>what is the point of setting the locale to something supporting
>Unicode?

I had problems with reading unicode symbols. Things like
define (Σ . args) : apply + args

> As-is, it now becomes impossible to use 'gettext' to translate
> software to non-English locales when the software imports (language
> wisp), which seems unfortunate to me.

That is very much not what I want.

> If you elaborate on what your
> goal here is, maybe I have an alternative solution.

This is to ensure that Wisp are always read as Unicode. Since it uses
regular (read) as part of parsing, it must affect (read), too.

>> + ;; allow using "# foo" as #(foo).
>> + (read-hash-extend #\# (λ (chr port) #\#))
>
> That's a rather Wisp-specific extension, but it appears you are
> extending things globally.  Instead, I propose extending it
> temporarily, with the undocumented '%read-hash-procedures' fluid.
>
>> +   (let
>> + (
>> +   (l
>
> Lonely parenthesis.

Thank you! Will be fixed :-)

> + (not (= 0 (line-real-indent (car lines ); -1 is a
> line with a comment
>
> Superfluous space after 'lines'.
>
>> + ; simple recursiive step to the next line
>
> I think the convention is ';;', OTOH there exist multiple conventions.
>
> +(define (wisp-scheme-replace-inline-colons lines)
> + "Replace inline colons by opening parens which close at the
> end of the line"
>
> Too much space; convention is two spaces.

> (Similar styles issues in other places.)
> "guix style" might be useful.

I’ll do that …

>> +(define (wisp-replace-paren-quotation-repr code)
>> + "Replace lists starting with a quotation symbol by
>> + quoted lists."
>> + (match code
>> + (('REPR-QUOTE-e749c73d-c826-47e2-a798-c16c13cb89dd a ...)
>> +(list 'quote (map wisp-replace-paren-quotation-repr a)))
>> [...]
>> +(define wisp-uuid "e749c73d-c826-47e2-a798-c16c13cb89dd")
>> +; define an intermediate dot replacement with UUID to avoid clashes.
>> +(define repr-dot ; .
>> +   (string->symbol (string-append "REPR-DOT-" wisp-uuid)))
>
> There is a risk of collision -- e.g., suppose that someone translates
> your implementation of Wisp into Wisp.  I imagine there might be a
> risk of misinterpreting the 'REPR-QUOTE-...' in
> wisp-replace-parent-quotation-repr, though I haven't tried it out.

This is actually auto-translated from wisp via wisp2lisp :-)

> As such, assuming this actually works, I propose using uninterned
> symbols instead, e.g.:
>
> (define repr-dot (make-symbol "REPR-DOT")).

That looks better — does uninterned symbol mean it can’t be
mis-interpreted?

Can I 

Re: [PATCH] add language/wisp to Guile?

2023-02-04 Thread Maxime Devos

Why add Wisp?

For Wisp: it is then available directly wherever Guile is available.
  This will make it much easier for people to follow tutorials.


I'm not convinced of this argument, because package managers exist, but ...


For Guile:

- Wisp has proven to be good at enabling people to get an
  entrance to Scheme² without pulling them out of the community.

> - [...]

... all good points, and the implementation of Wisp is tiny anyway.  For 
an additional reason: Wisp is a SRFI (Scheme Requests for 
Implementation) and Guile is a Scheme implementation.



So I’d like to ask: can we merge Wisp as supported language into Guile?


From some conversations elsewhere, I got the impression that

(use-modules (foo))

will search for foo.scm and not in foo.w.  I think you'll need to tweak 
the loading mechanism to also look for foo.w instead of only foo.scm, if 
not done already.


Also, I think that when foo.go exists, but foo.scm doesn't, then Guile 
refuses to load foo.scm, though I'm less sure of that.  If this is the 
case, I propose removing the requirement that the source code is 
available, or alternatively keep the 'source code available' requirement 
and also accept 'foo.w', if not done already.


> +; Set locale to something which supports unicode. Required to avoid
> using fluids.
> +(catch #t

 * Why avoid fluids?
 * Assuming for sake of argument that fluids are to be avoided,
   what is the point of setting the locale to something supporting
   Unicode?

As-is, it now becomes impossible to use 'gettext' to translate software 
to non-English locales when the software imports (language wisp), which 
seems unfortunate to me.  If you elaborate on what your goal here is, 
maybe I have an alternative solution.



+ ;; allow using "# foo" as #(foo).
+ (read-hash-extend #\# (λ (chr port) #\#))


That's a rather Wisp-specific extension, but it appears you are 
extending things globally.  Instead, I propose extending it temporarily, 
with the undocumented '%read-hash-procedures' fluid.



+   (let
+ (
+   (l


Lonely parenthesis.

+ (not (= 0 (line-real-indent (car lines ); -1 is a line 
with a comment


Superfluous space after 'lines'.


+ ; simple recursiive step to the next line


I think the convention is ';;', OTOH there exist multiple conventions.

+(define (wisp-scheme-replace-inline-colons lines)
+ "Replace inline colons by opening parens which close at the 
end of the line"


Too much space; convention is two spaces.

(Similar styles issues in other places.)
"guix style" might be useful.


+(define (wisp-replace-paren-quotation-repr code)
+ "Replace lists starting with a quotation symbol by
+ quoted lists."
+ (match code
+ (('REPR-QUOTE-e749c73d-c826-47e2-a798-c16c13cb89dd a ...)
+(list 'quote (map wisp-replace-paren-quotation-repr a)))
[...]
+(define wisp-uuid "e749c73d-c826-47e2-a798-c16c13cb89dd")
+; define an intermediate dot replacement with UUID to avoid clashes.
+(define repr-dot ; .
+   (string->symbol (string-append "REPR-DOT-" wisp-uuid)))


There is a risk of collision -- e.g., suppose that someone translates 
your implementation of Wisp into Wisp.  I imagine there might be a risk 
of misinterpreting the 'REPR-QUOTE-...' in 
wisp-replace-parent-quotation-repr, though I haven't tried it out.


As such, assuming this actually works, I propose using uninterned 
symbols instead, e.g.:


(define repr-dot (make-symbol "REPR-DOT")).

If this change is done, you might need to replace

+ ;; literal array as start of a line: # (a b) c -> (#(a b) c)
+ ((#\# a ...)
+   (with-input-from-string ;; hack to defer to read
+   (string-append "#"
+   (with-output-to-string
+   (λ ()
+ (write (map 
wisp-replace-paren-quotation-repr a)

+ (current-output-port)
+   read))


(unverified -- I think removing this is unneeded but I don't understand 
this REPR-... stuff well enough).


Also, I wonder if you could just do something like

  (apply vector (map wisp-replace-paren-quotation-repr a))

instead of this 'hack to defer to read' thing.  This seems simpler to me 
and equivalent.


(AFAIK, these REPR-... symbols are never written to a port or turned 
into syntax, so I think that uninterned symbols would work here.)


(Aside from the REPR-... thing, I'm assuming (language wisp) is alright 
-- the SRFI is in 'final' status and it has been stable for years now, 
after all.)


Greetings,
Maxime


OpenPGP_0x49E3EE22191725EE.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature