Jump to page: 1 2
Thread overview
Alternate string literal syntax (with mixins)?
Feb 11, 2007
Kristian Kilpi
Feb 11, 2007
Johan Granberg
Feb 11, 2007
Johan Granberg
Feb 11, 2007
Kristian Kilpi
Feb 12, 2007
Bill Baxter
Feb 12, 2007
Kristian Kilpi
Feb 11, 2007
Kristian Kilpi
Feb 11, 2007
janderson
Feb 12, 2007
Xinok
Feb 12, 2007
Lionello Lunesu
Feb 13, 2007
Stewart Gordon
Feb 13, 2007
Kristian Kilpi
Feb 16, 2007
janderson
Feb 16, 2007
janderson
Feb 16, 2007
Kristian Kilpi
Feb 16, 2007
janderson
Extension: Alternate string literal syntax (mixins, DSLs)
Feb 18, 2007
Kristian Kilpi
February 11, 2007
String literals with mixins are a bit awkward sometimes (editor highlighting etc).

Some special marks -- I use @{ }@ here -- could be used to mark a part of a source file as a string literal, just like /* */ marks a part of code as a comment. For example:

  mixin(
    @{
      //this is a string literal block
      if(...) {
        ...
      }
    }@
  );

The @{ }@ marks have a close relation, of course, with quotation marks "". But because there is a starting mark and an ending mark, you can nest them. (And because they are used to mark a part of a file as a string literal, they are not actually the part of the 'working code' just like the "" literals are, if you get what I'm trying to say.)

E.g.

  alias @{
    str = @{ foo }@ ~ @{ bar }@;
    str ~= "blah";
    if(...) {
      ...
    }
  }@ MyCode;

   mixin(MyCode);
February 11, 2007
Kristian Kilpi wrote:

> 
> String literals with mixins are a bit awkward sometimes (editor
> highlighting etc).
> 
> Some special marks -- I use @{ }@ here -- could be used to mark a part of a source file as a string literal, just like /* */ marks a part of code as a comment. For example:
> 
>    mixin(
>      @{
>        //this is a string literal block
>        if(...) {
>          ...
>        }
>      }@
>    );
> 
> The @{ }@ marks have a close relation, of course, with quotation marks "". But because there is a starting mark and an ending mark, you can nest them. (And because they are used to mark a part of a file as a string literal, they are not actually the part of the 'working code' just like the "" literals are, if you get what I'm trying to say.)
> 
> E.g.
> 
>    alias @{
>      str = @{ foo }@ ~ @{ bar }@;
>      str ~= "blah";
>      if(...) {
>        ...
>      }
>    }@ MyCode;
> 
>     mixin(MyCode);

Wouldn't it be a better solution if the escape syntax you described represented a custom format that mixins was thought to handle? What I'm thingking is something like lisps quotes, then the escaped code could be tokenized and we could modify tokens instead of strings. (for a small fraction of cases the string might be better but then we could have the current syntax)
February 11, 2007
Johan Granberg wrote:

> Kristian Kilpi wrote:
> 
>> 
>> String literals with mixins are a bit awkward sometimes (editor
>> highlighting etc).
>> 
>> Some special marks -- I use @{ }@ here -- could be used to mark a part of a source file as a string literal, just like /* */ marks a part of code as a comment. For example:
>> 
>>    mixin(
>>      @{
>>        //this is a string literal block
>>        if(...) {
>>          ...
>>        }
>>      }@
>>    );
>> 
>> The @{ }@ marks have a close relation, of course, with quotation marks "". But because there is a starting mark and an ending mark, you can nest them. (And because they are used to mark a part of a file as a string literal, they are not actually the part of the 'working code' just like the "" literals are, if you get what I'm trying to say.)
>> 
>> E.g.
>> 
>>    alias @{
>>      str = @{ foo }@ ~ @{ bar }@;
>>      str ~= "blah";
>>      if(...) {
>>        ...
>>      }
>>    }@ MyCode;
>> 
>>     mixin(MyCode);
> 
> Wouldn't it be a better solution if the escape syntax you described represented a custom format that mixins was thought to handle? What I'm thingking is something like lisps quotes, then the escaped code could be tokenized and we could modify tokens instead of strings. (for a small fraction of cases the string might be better but then we could have the current syntax)

While I'm at it I might suggest using <[ and ]> as tokens instead of @{. This is the tokens used in nemerle (if I understood their manual right) and it is unnecessary to use a different token just because.

http://nemerle.org/Syntax_extensions

February 11, 2007
On Sun, 11 Feb 2007 18:39:35 +0200, Johan Granberg <lijat.meREM@OVE.gmail.com> wrote:
> Kristian Kilpi wrote:
>
>>
>> String literals with mixins are a bit awkward sometimes (editor
>> highlighting etc).
>>
>> Some special marks -- I use @{ }@ here -- could be used to mark a part of
>> a source file as a string literal, just like /* */ marks a part of code as
>> a comment. For example:
>>
>>    mixin(
>>      @{
>>        //this is a string literal block
>>        if(...) {
>>          ...
>>        }
>>      }@
>>    );
>>
>> The @{ }@ marks have a close relation, of course, with quotation marks "".
>> But because there is a starting mark and an ending mark, you can nest
>> them. (And because they are used to mark a part of a file as a string
>> literal, they are not actually the part of the 'working code' just like
>> the "" literals are, if you get what I'm trying to say.)
>>
>> E.g.
>>
>>    alias @{
>>      str = @{ foo }@ ~ @{ bar }@;
>>      str ~= "blah";
>>      if(...) {
>>        ...
>>      }
>>    }@ MyCode;
>>
>>     mixin(MyCode);
>
> Wouldn't it be a better solution if the escape syntax you described
> represented a custom format that mixins was thought to handle? What I'm
> thingking is something like lisps quotes, then the escaped code could be
> tokenized and we could modify tokens instead of strings. (for a small
> fraction of cases the string might be better but then we could have the
> current syntax)


Sounds like a good idea. :) That would/could simplify things. Hmm, I'm wondering if tuples could be used here?
February 11, 2007
Johan Granberg wrote:
> Johan Granberg wrote:
> 
>> Kristian Kilpi wrote:
>>
>>> String literals with mixins are a bit awkward sometimes (editor
>>> highlighting etc).
>>>
>>> Some special marks -- I use @{ }@ here -- could be used to mark a part of
>>> a source file as a string literal, just like /* */ marks a part of code
>>> as a comment. For example:
>>>
>>>    mixin(
>>>      @{
>>>        //this is a string literal block
>>>        if(...) {
>>>          ...
>>>        }
>>>      }@
>>>    );
>>>
>>> The @{ }@ marks have a close relation, of course, with quotation marks
>>> "". But because there is a starting mark and an ending mark, you can nest
>>> them. (And because they are used to mark a part of a file as a string
>>> literal, they are not actually the part of the 'working code' just like
>>> the "" literals are, if you get what I'm trying to say.)
>>>
>>> E.g.
>>>
>>>    alias @{
>>>      str = @{ foo }@ ~ @{ bar }@;
>>>      str ~= "blah";
>>>      if(...) {
>>>        ...
>>>      }
>>>    }@ MyCode;
>>>
>>>     mixin(MyCode);
>> Wouldn't it be a better solution if the escape syntax you described
>> represented a custom format that mixins was thought to handle? What I'm
>> thingking is something like lisps quotes, then the escaped code could be
>> tokenized and we could modify tokens instead of strings. (for a small
>> fraction of cases the string might be better but then we could have the
>> current syntax)
> 
> While I'm at it I might suggest using <[ and ]> as tokens instead of @{.
> This is the tokens used in nemerle (if I understood their manual right) and
> it is unnecessary to use a different token just because. 
> 
> http://nemerle.org/Syntax_extensions

Probably best is to use one group of symbols that nest naturally (e.g. [] or () or {}) and prefix them with something that unambiguously denotes a string:

alias ${
  ... anything with balanced {}'s ...
  ... or with unbalanced \{ and \}'s ...
} MyCode;

or:

alias $(
  ... anything with balanced ()'s ...
  ... or with unbalanced \( and \)'s ...
) MyCode;

or:

alias $[
  ... anything with balanced []'s ...
  ... or with unbalanced \[ and \]'s ...
] MyCode;

This should reasonably cover applications elegantly, especially because code tends to not have three kinds of unbalanced parens at the same time :o).


Andrei
February 11, 2007
On Sun, 11 Feb 2007 20:08:59 +0200, Andrei Alexandrescu (See Website For Email) <SeeWebsiteForEmail@erdani.org> wrote:
> Johan Granberg wrote:
>> Johan Granberg wrote:
>>
>>> Kristian Kilpi wrote:
>>>
>>>> String literals with mixins are a bit awkward sometimes (editor
>>>> highlighting etc).
>>>>
>>>> Some special marks -- I use @{ }@ here -- could be used to mark a part of
>>>> a source file as a string literal, just like /* */ marks a part of code
>>>> as a comment. For example:
>>>>
>>>>    mixin(
>>>>      @{
>>>>        //this is a string literal block
>>>>        if(...) {
>>>>          ...
>>>>        }
>>>>      }@
>>>>    );
>>>>
>>>> The @{ }@ marks have a close relation, of course, with quotation marks
>>>> "". But because there is a starting mark and an ending mark, you can nest
>>>> them. (And because they are used to mark a part of a file as a string
>>>> literal, they are not actually the part of the 'working code' just like
>>>> the "" literals are, if you get what I'm trying to say.)
>>>>
>>>> E.g.
>>>>
>>>>    alias @{
>>>>      str = @{ foo }@ ~ @{ bar }@;
>>>>      str ~= "blah";
>>>>      if(...) {
>>>>        ...
>>>>      }
>>>>    }@ MyCode;
>>>>
>>>>     mixin(MyCode);
>>> Wouldn't it be a better solution if the escape syntax you described
>>> represented a custom format that mixins was thought to handle? What I'm
>>> thingking is something like lisps quotes, then the escaped code could be
>>> tokenized and we could modify tokens instead of strings. (for a small
>>> fraction of cases the string might be better but then we could have the
>>> current syntax)
>>  While I'm at it I might suggest using <[ and ]> as tokens instead of @{.
>> This is the tokens used in nemerle (if I understood their manual right) and
>> it is unnecessary to use a different token just because.  http://nemerle.org/Syntax_extensions
>
> Probably best is to use one group of symbols that nest naturally (e.g. [] or () or {}) and prefix them with something that unambiguously denotes a string:
>
> alias ${
>    ... anything with balanced {}'s ...
>    ... or with unbalanced \{ and \}'s ...
> } MyCode;
>
> or:
>
> alias $(
>    ... anything with balanced ()'s ...
>    ... or with unbalanced \( and \)'s ...
> ) MyCode;
>
> or:
>
> alias $[
>    ... anything with balanced []'s ...
>    ... or with unbalanced \[ and \]'s ...
> ] MyCode;
>
> This should reasonably cover applications elegantly, especially because code tends to not have three kinds of unbalanced parens at the same time :o).
>
>
> Andrei

Actually I was first considering a @{ } syntax. Then I decided to add the second @ (i.e. @{ }@ ) so that unbalanced curly bracets would be allowed without escape sequencing them (e.g. \{ \} ). This allows one to construct strings from smaller parts containing unbalanced parens that would otherwise be balanced, e.g.:

  @{ if(...) { }@ ~ Block!() ~ @{ } }@
->
  " if(...) { " ~ Block!() ~ " } "

Well, a syntax with only one @ (or $) looks nicer though.

The second thing I was considering (with the @{ } syntax) was a different way to create user defined string literals, e.g.:

  @MyCode {
    ...
  }

  mixin(@MyCode);

User defined literals would then belong to their own unique namespace (@MyCode versus MyCode), which could be nice (or not).
February 11, 2007
Kristian Kilpi wrote:
> On Sun, 11 Feb 2007 20:08:59 +0200, Andrei Alexandrescu (See Website For Email) <SeeWebsiteForEmail@erdani.org> wrote:
>> Johan Granberg wrote:
>>> Johan Granberg wrote:
>>>
>>>> Kristian Kilpi wrote:
>>>>
>>>>> String literals with mixins are a bit awkward sometimes (editor
>>>>> highlighting etc).
>>>>>
>>>>> Some special marks -- I use @{ }@ here -- could be used to mark a part of
>>>>> a source file as a string literal, just like /* */ marks a part of code
>>>>> as a comment. For example:
>>>>>
>>>>>    mixin(
>>>>>      @{
>>>>>        //this is a string literal block
>>>>>        if(...) {
>>>>>          ...
>>>>>        }
>>>>>      }@
>>>>>    );
>>>>>
>>>>> The @{ }@ marks have a close relation, of course, with quotation marks
>>>>> "". But because there is a starting mark and an ending mark, you can nest
>>>>> them. (And because they are used to mark a part of a file as a string
>>>>> literal, they are not actually the part of the 'working code' just like
>>>>> the "" literals are, if you get what I'm trying to say.)
>>>>>
>>>>> E.g.
>>>>>
>>>>>    alias @{
>>>>>      str = @{ foo }@ ~ @{ bar }@;
>>>>>      str ~= "blah";
>>>>>      if(...) {
>>>>>        ...
>>>>>      }
>>>>>    }@ MyCode;
>>>>>
>>>>>     mixin(MyCode);
>>>> Wouldn't it be a better solution if the escape syntax you described
>>>> represented a custom format that mixins was thought to handle? What I'm
>>>> thingking is something like lisps quotes, then the escaped code could be
>>>> tokenized and we could modify tokens instead of strings. (for a small
>>>> fraction of cases the string might be better but then we could have the
>>>> current syntax)
>>>  While I'm at it I might suggest using <[ and ]> as tokens instead of @{.
>>> This is the tokens used in nemerle (if I understood their manual right) and
>>> it is unnecessary to use a different token just because.  http://nemerle.org/Syntax_extensions
>>
>> Probably best is to use one group of symbols that nest naturally (e.g. [] or () or {}) and prefix them with something that unambiguously denotes a string:
>>
>> alias ${
>>    ... anything with balanced {}'s ...
>>    ... or with unbalanced \{ and \}'s ...
>> } MyCode;
>>
>> or:
>>
>> alias $(
>>    ... anything with balanced ()'s ...
>>    ... or with unbalanced \( and \)'s ...
>> ) MyCode;
>>
>> or:
>>
>> alias $[
>>    ... anything with balanced []'s ...
>>    ... or with unbalanced \[ and \]'s ...
>> ] MyCode;
>>
>> This should reasonably cover applications elegantly, especially because code tends to not have three kinds of unbalanced parens at the same time :o).
>>
>>
>> Andrei
> 
> Actually I was first considering a @{ } syntax. Then I decided to add the second @ (i.e. @{ }@ ) so that unbalanced curly bracets would be allowed without escape sequencing them (e.g. \{ \} ). This allows one to construct strings from smaller parts containing unbalanced parens that would otherwise be balanced, e.g.:
> 
>   @{ if(...) { }@ ~ Block!() ~ @{ } }@
> ->
>   " if(...) { " ~ Block!() ~ " } "
> 
> Well, a syntax with only one @ (or $) looks nicer though.

And Perl programmers will love it. :o) Perl probably has the most comprehensive string notation capabilities, and it's very well thought out.


Andrei
February 11, 2007
Kristian Kilpi wrote:
> 
> String literals with mixins are a bit awkward sometimes (editor highlighting etc).
> 
> Some special marks -- I use @{ }@ here -- could be used to mark a part of a source file as a string literal, just like /* */ marks a part of code as a comment. For example:
> 
>   mixin(
>     @{
>       //this is a string literal block
>       if(...) {
>         ...
>       }
>     }@
>   );
> 
> The @{ }@ marks have a close relation, of course, with quotation marks "". But because there is a starting mark and an ending mark, you can nest them. (And because they are used to mark a part of a file as a string literal, they are not actually the part of the 'working code' just like the "" literals are, if you get what I'm trying to say.)
> 
> E.g.
> 
>   alias @{
>     str = @{ foo }@ ~ @{ bar }@;
>     str ~= "blah";
>     if(...) {
>       ...
>     }
>   }@ MyCode;
> 
>    mixin(MyCode);

It's a good idea.  Whatever the symbols are, they should be nestable and should be generic so they can be used for normal strings.

-Joel
February 12, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Kristian Kilpi wrote:
>> On Sun, 11 Feb 2007 20:08:59 +0200, Andrei Alexandrescu (See Website For Email) <SeeWebsiteForEmail@erdani.org> wrote:
>>> Johan Granberg wrote:
>>>> Johan Granberg wrote:
>>>>
>>>>> Kristian Kilpi wrote:
>>>>>
>>>>>> String literals with mixins are a bit awkward sometimes (editor
>>>>>> highlighting etc).
>>>>>>
>>>>>> Some special marks -- I use @{ }@ here -- could be used to mark a part of
>>>>>> a source file as a string literal, just like /* */ marks a part of code
>>>>>> as a comment. For example:
>>>>>>
>>>>>>    mixin(
>>>>>>      @{
>>>>>>        //this is a string literal block
>>>>>>        if(...) {
>>>>>>          ...
>>>>>>        }
>>>>>>      }@
>>>>>>    );
>>>>>>
>>>>>> The @{ }@ marks have a close relation, of course, with quotation marks
>>>>>> "". But because there is a starting mark and an ending mark, you can nest
>>>>>> them.

I like these ideas.
Here's another thought -- just let "mixin" be followed directly by a string literal.

Then this:
#    mixin(
#      @{
#        //this is a string literal block
#        if(...) {
#          ...
#        }
#      }@
#    );

becomes:
#    mixin@{
#        //this is a string literal block
#        if(...) {
#          ...
#        }
#    }@;


 (And because they are used to mark a part of a file as a string
>>>>>> literal, they are not actually the part of the 'working code' just like
>>>>>> the "" literals are, if you get what I'm trying to say.)
>>>>>>
>>>>>> E.g.
>>>>>>
>>>>>>    alias @{
>>>>>>      str = @{ foo }@ ~ @{ bar }@;
>>>>>>      str ~= "blah";
>>>>>>      if(...) {
>>>>>>        ...
>>>>>>      }
>>>>>>    }@ MyCode;
>>>>>>
>>>>>>     mixin(MyCode);

I like this too.

Related but somewhat different would be the concept of importing chunks from the /current/ file.
Now with import("foo.txt") we can import the entire contents of an arbitrary file as a string, but that introduces some distance between the content and where it is used.  Sometimes you want locality.  Say I've got a little 5-line shader program that I'm using.  In c++ I'll often start out putting it in the same file near the point of use with an embedded string.  Despite code in strings being kind of a pain to work with, it's still less annoying than going back and forth between two files to make sure I keep the parameter names in the C++ file in sync with shader code as I tweak things.

Maybe your string alias idea is enough for that.  I think the wisdom of perl, though, is that if the token delimiting start-of-string is fixed, then as soon as you start manipulating code that manipulates code, you end up finding you want to embed that very token in a text literal, and need to escape it.  Using nest-able symbols helps but doesn't solve the problem if you want to have a literal "@{" without it's mate in the block.  It's the same reason you wanted to have @{ }@,  so you could nest { and } independantly.  The same need will arise for @{ and }@.

Perl's solution ("here documents") is to make it possible to make unique delimiters that are very much less likely to clash with anything in arbitrary code fragments:

<<"SomeUniqueStringICameUpWithToSignalTheEND";
stuff here
more "stuff"
   whitespace is all significant
   "quotes" don't matter
SomeStringICameUpWithToSignalTheEND


I don't care what the syntax is, but if I'm going to be manipulating lots of quoted code, I want something like Perl's here documents, so that I can paste anything I want in between the start and end markers and know that it'll just work (with 1-epsilon probability).

It might also be nice to combine that with the import chunk idea so that the label could be used to import the chunk:

   import(SomeUniqueStringICameUpWithToSignalTheEND);

--bb
February 12, 2007
Just throwing another suggestion out there for tokens, I personally like </ />. I find them easier to type and easier to read without the need for an editor to highlight them.


>    alias </
>      str = </ foo /> ~ </ bar />;
>      str ~= "blah";
>      if(...) {
>        ...
>      }
>    /> MyCode;
> 
>     mixin(MyCode);
« First   ‹ Prev
1 2