From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Noah Lavine Newsgroups: gmane.lisp.guile.devel Subject: Re: non-scheme scripts: proposed solutions and their pros/cons Date: Tue, 20 Nov 2012 08:14:46 -0500 Message-ID: References: <87boesxyfp.fsf@googlemail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=bcaec54d41a897926504ceed04bd X-Trace: ger.gmane.org 1353417305 3592 80.91.229.3 (20 Nov 2012 13:15:05 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 20 Nov 2012 13:15:05 +0000 (UTC) Cc: Guile Mailing List To: Ian Price Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Tue Nov 20 14:15:14 2012 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1TanfV-0003iZ-C5 for guile-devel@m.gmane.org; Tue, 20 Nov 2012 14:15:13 +0100 Original-Received: from localhost ([::1]:47952 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TanfK-0002T6-RS for guile-devel@m.gmane.org; Tue, 20 Nov 2012 08:15:02 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:49303) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tanf7-0002Pu-QA for guile-devel@gnu.org; Tue, 20 Nov 2012 08:15:00 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tanf5-0003Ol-9i for guile-devel@gnu.org; Tue, 20 Nov 2012 08:14:49 -0500 Original-Received: from mail-oa0-f41.google.com ([209.85.219.41]:37071) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tanf5-0003OZ-2O for guile-devel@gnu.org; Tue, 20 Nov 2012 08:14:47 -0500 Original-Received: by mail-oa0-f41.google.com with SMTP id k14so6697295oag.0 for ; Tue, 20 Nov 2012 05:14:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=tBXePpfYNzIrvF709Wc/PM4877TG4AG9N3Opv9kW3sY=; b=p0W0V76Q3kAhTUUJ6r1tnimVINGTPyQHl17s03KdB04rB/pkzzQGcV+P488NiqF9Rb D44oNvbBTRHepWySTjPjAWuttsSQfmgPs2s0rPqIwwANkoUOm5i6BPiUFOuzY3eQuu2J vYWSJ3fxpymS/ohd9fEgiXA/9ireJ/ELj0iiIdKlggFDdL4bvd8+uCy6COfsEm1rD5RA fOOOukP7qbBPa7pg5VT19oGTKkDIHiE+mGP+1R3fZ9YopZTDrJu5T4z7DMlveAp44naa 94MdZ9Pf00m3UWHDRsf44E6W+7q4PazApAKxS021SSv4HSkXmInd650KXiT8jk9CV/F3 urQQ== Original-Received: by 10.60.172.138 with SMTP id bc10mr13557851oec.33.1353417286455; Tue, 20 Nov 2012 05:14:46 -0800 (PST) Original-Received: by 10.76.120.236 with HTTP; Tue, 20 Nov 2012 05:14:46 -0800 (PST) In-Reply-To: <87boesxyfp.fsf@googlemail.com> X-Google-Sender-Auth: c7b4S9yR2U7a8XcvVdfPrIuOFi0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.219.41 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:15217 Archived-At: --bcaec54d41a897926504ceed04bd Content-Type: text/plain; charset=ISO-8859-1 As you say, the only real solution is to do more than one of these things. For instance, I think it's really important to be able to load modules written in other languages. However, this may be language-dependent to a certain extent, because some languages (Python) already have ways to define modules. In those cases we should stick with their conventions, and use our other methods for figuring out what language the file is in. However, if we're using Guile in one language and loading an executable in a different language, then we can't use a command-line argument or a different executable to signal it. The only choices left are heuristics and explicit markers. I think the only reasonable choice is both - use heuristics, and let the user supply a marker if the heuristics are wrong. (In the module case, one can imagine a heuristic based on having a language-specific load path for each language, which might be very effective.) But for using Guile as an interpreter for different languages, a command-line argument or argv[0] switch make a lot of sense. What do you think? Noah On Tue, Nov 20, 2012 at 7:15 AM, Ian Price wrote: > > As promised in the other thread, here is my list. This was really a > response to the even the earlier thread I started, which I > (unfortunately) didn't reply to at the time. > > First off, they important question "why do we need this?". Well, guile > is a multi-language vm in principle, even if Scheme is it's first and > foremost citizen. If guile is to be a full-fledged vm for these other > languages, they need all (or at least most of) the rights and privileges > scheme does. This includes the ability to be run as scripts. > > So, what are the solutions? Well, a few have cropped up, but I'm not > sure that individually any of them constitute a complete > solution. They are: a command-line argument, some marker in the > module, a different executable, and heuristics based on file > extension. > > I shall treat these in order, though I can't pretend I will be > comprehensive. Clarifications and additions welcome. > > > * a command line argument > This was the position I initially proposed, and so had some bias > towards. The idea is very simple, we add a --language extension, the > argument to which would be the language of the file(s) we are trying > to execute. > > ** Pros > - Existing source files in the language do not need to be modified to > use this. > - Requires (in theory) modifying only the command-line parsing > > ** Cons > - Has nothing to say about how e.g. scheme modules interact with elisp > modules. > - #! only gives you one argument, and not all languages are going to > support a \ type solution > > * a file marker > The idea here it to have some way of marking in a file which language > it is written in, with some token like #!javascript, or perhaps > something like #!language javascript > > ** Pros > - works well with current module system > e.g. say we have a file foo/bar.js and that had a #!javascript > marker, then I could (use-modules (foo bar)) and guile would notice > the marker, switch to javascript mode for it. > - we already do this for switching to curly-infix and r6rs reader > modes > > ** Cons > - requires modifying existing source code, I couldn't just import an > existing elisp (or whatever) file and use as is. > - the existing mechanism allows switching reader mode at an arbitrary > part of the file. Not a big con, for #!language, I would simply say > we disallow it in arbitrary places. However, people that extend > guile as a language (i.e. lilypond), might disagree and would want > to take advantage of this. > > * different executable > This was a position posed in response to mine, that I was initially > against, but am somewhat more open to now. The idea is that for every > language $foo, we have a script guile-$foo which invokes that > language. > Technically it need not be a different executable, but one whose > action depends on argv[0] and just performs the appropriate action, > but in many respects these can be treated the same. > > ** Pros > - Existing source files in the language do not need to be modified to > use this, they can change the existing languages symlink. > - We can handle common switches used by the language > - If you go for argv[0], may only require modifying the command-line > parsing. > > ** Cons > - proliferation of names, even if just symlinks > - has nothing to say about cross-language interoperability > > > * heuristics > This always gets proposed, and I never like it, but hey ho. The idea > is to have some simple way to guess what language a file is written > in, for example, with a mapping of file extensions to languages. > > ** Pros > Best case scenario, you do nothing. You type guile foo.js, and it just > works. > - same excutable name > - don't need to modify existing code > > ** Cons > *** guessing on file extension > - guile allows user defined extensions > Need to have a way of associating modes with new extensions > - some language share extensions > I'm thinking of .pl for perl and prolog, but I'm sure there are > other conflicts. Might not be a big con in practice > - Many files don't have an extension, think running with ./foo > *** guessing on content type > - Seems complicated to implement, especially for syntactically close > languages. Probably undecidable in general. > > > My thanks to William Leslie[0], Neil Jerram[1], and quotemstr on #emacs for > pointing out various pros/cons. > > > So, the million dollar question: what do we do? > > Well, I don't know. :) > > Maybe the argv[0] solution, with some extension for requiring modules > in other languages built into use-modules (similarly for other > languages). But that's less nice since now the calling module needs to > know the language of the module it's requiring. > > 0. https://lists.gnu.org/archive/html/guile-devel/2012-07/msg00067.html > 1. https://lists.gnu.org/archive/html/guile-devel/2012-07/msg00068.html > > -- > Ian Price -- shift-reset.com > > "Programming is like pinball. The reward for doing it well is > the opportunity to do it again" - from "The Wizardy Compiled" > > --bcaec54d41a897926504ceed04bd Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable As you say, the only real solution is to do more than one of these things.<= div>
For instance, I think it's really important to be ab= le to load modules written in other languages. However, this may be languag= e-dependent to a certain extent, because some languages (Python) already ha= ve ways to define modules. In those cases we should stick with their conven= tions, and use our other methods for figuring out what language the file is= in.

However, if we're using Guile in one language and l= oading an executable in a different language, then we can't use a comma= nd-line argument or a different executable to signal it. The only choices l= eft are heuristics and explicit markers. I think the only reasonable choice= is both - use heuristics, and let the user supply a marker if the heuristi= cs are wrong. (In the module case, one can imagine a heuristic based on hav= ing a language-specific load path for each language, which might be very ef= fective.)

But for using Guile as an interpreter for different lan= guages, a command-line argument or argv[0] switch make a lot of sense.

What do you think?
Noah



On Tue, Nov 2= 0, 2012 at 7:15 AM, Ian Price <ianprice90@googlemail.com> wrote:

As promised in the other thread, here is my list. This was really a
response to the even the earlier thread I started, which I
(unfortunately) didn't reply to at the time.

First off, they important question "why do we need this?". Well, = guile
is a multi-language vm in principle, even if Scheme is it's first and foremost citizen. If guile is to be a full-fledged vm for these other
languages, they need all (or at least most of) the rights and privileges scheme does. This includes the ability to be run as scripts.

So, what are the solutions? Well, a few have cropped up, but I'm not sure that individually any of them constitute a complete
solution. They are: a command-line argument, some marker in the
module, a different executable, and heuristics based on file
extension.

I shall treat these in order, though I can't pretend I will be
comprehensive. Clarifications and additions welcome.


* a command line argument
This was the position I initially proposed, and so had some bias
towards. The idea is very simple, we add a --language extension, the
argument to which would be the language of the file(s) we are trying
to execute.

** Pros
- Existing source files in the language do not need to be modified to
=A0 use this.
- Requires (in theory) modifying only the command-line parsing

** Cons
- Has nothing to say about how e.g. scheme modules interact with elisp modu= les.
- #! only gives you one argument, and not all languages are going to
=A0 support a \ type solution

* a file marker
The idea here it to have some way of marking in a file which language
it is written in, with some token like #!javascript, or perhaps
something like #!language javascript

** Pros
- works well with current module system
=A0 e.g. say we have a file foo/bar.js and that had a #!javascript
=A0 marker, then I could (use-modules (foo bar)) and guile would notice
=A0 the marker, switch to javascript mode for it.
- we already do this for switching to curly-infix and r6rs reader
=A0 modes

** Cons
- requires modifying existing source code, I couldn't just import an =A0 existing elisp (or whatever) file and use as is.
- the existing mechanism allows switching reader mode at an arbitrary
=A0 part of the file. Not a big con, for #!language, I would simply say
=A0 we disallow it in arbitrary places. However, people that extend
=A0 guile as a language (i.e. lilypond), might disagree and would want
=A0 to take advantage of this.

* different executable
This was a position posed in response to mine, that I was initially
against, but am somewhat more open to now. The idea is that for every
language $foo, we have a script guile-$foo which invokes that
language.
Technically it need not be a different executable, but one whose
action depends on argv[0] and just performs the appropriate action,
but in many respects these can be treated the same.

** Pros
- Existing source files in the language do not need to be modified to
=A0 use this, they can change the existing languages symlink.
- We can handle common switches used by the language
- If you go for argv[0], may only require modifying the command-line
=A0 parsing.

** Cons
- proliferation of names, even if just symlinks
- has nothing to say about cross-language interoperability


* heuristics
This always gets proposed, and I never like it, but hey ho. The idea
is to have some simple way to guess what language a file is written
in, for example, with a mapping of file extensions to languages.

** Pros
Best case scenario, you do nothing. You type guile foo.js, and it just
works.
- same excutable name
- don't need to modify existing code

** Cons
*** guessing on file extension
- guile allows user defined extensions
=A0 Need to have a way of associating modes with new extensions
- some language share extensions
=A0 I'm thinking of .pl for perl and prolog, but I'm sure there are=
=A0 other conflicts. Might not be a big con in practice
- Many files don't have an extension, think running with ./foo
*** guessing on content type
- Seems complicated to implement, especially for syntactically close
=A0 languages. Probably undecidable in general.


My thanks to William Leslie[0], Neil Jerram[1], and quotemstr on #emacs for=
pointing out various pros/cons.


So, the million dollar question: what do we do?

Well, I don't know. :)

Maybe the argv[0] solution, with some extension for requiring modules
in other languages built into use-modules (similarly for other
languages). But that's less nice since now the calling module needs to<= br> know the language of the module it's requiring.

0. https://lists.gnu.org/archive/html/guile-devel/2= 012-07/msg00067.html
1. https://lists.gnu.org/archive/html/guile-devel/2= 012-07/msg00068.html

--
Ian Price -- shift-res= et.com

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"= ;


--bcaec54d41a897926504ceed04bd--