2009/8/12 Guillaume Nodet <gno...@gmail.com>

> The problem is how to make the distinction between grouping and evaluation.
>
> In unix, we have the following:
> > echo echo a
> a
> > (echo echo a)
> echo a
> > ( (echo echo a) )
> echo a
> > $(echo echo a)
> a
> > $( $(echo echo a) )
> -bash: a: command not found
> > $( (echo echo a) )
> a
> > ( $(echo echo a) )
> a
>
> So we have a clear difference between () and $(), where () is only for
> grouping and has no effect on the evaluation, while $() will evaluate the
> content.


This is not quite true.

Unix always expects the word following '(' to be a command that it executes,
so () is NOT only for grouping, as its contents is executed as a command
pipeline.

$() first executes the contents just like (), and then it captures the
standard output and returns it as a string.

Note: in Unix, '(' can only appear where a command can appear, so the
following causes a syntax error:

$ echo hello (date)
-bash: syntax error near unexpected token `('


Gogo should allow () anywhere in a command line, and it should be replaced
by the value of the executed pipeline. This is possible in Gogo, because
commands can operate directly on Objects, not just strings like bash.

If we do use use $() in Gogo, then it should capture the output of the
command and replace it with a string.
However, this is less important, as most commands can deal with the object
directly. Those that can't can use 'tac'.



>
>
> The grouping operator is imho needed to be able to order pipes and columns:
>   (echo a ; echo b) | tac
>   echo a ; (echo b | tac)



I agree that we need the ability to control ordering.

However, this example works fine with the existing <> execution quotes:

ka...@root> <echo a; echo b> | tac
ab
ka...@root> echo a; <echo b | tac>
a
b

Now if I remove the ; so the result of the execution becomes an argument of
the first echo,
the result we get is intuitive:

ka...@root> echo a <echo b | tac>
ab


I have also compiled karaf using the FELIX-1471 patch:

The commands in the example also work as expected:

ka...@root> (echo a; echo b) | tac
ab
ka...@root> echo a; (echo b | tac)
a
b

but now when I remove the ; I get a non-intuitive result:

ka...@root> echo a (echo b | tac)
a(echo b | tac)

i.e. the () only cause execution at the beginning of a command.
so I'm now forced to use $() which seems unnecessary:

ka...@root> echo a $(echo b | tac)
ab


Ideally we would use the Unix default ordering, so that

echo a; echo b | tac

is treated as:

echo a; (echo b | tac)

Derek



>
>
> I think it might be confusing to conflate the two operators.  We could use
> (( ... )) as an operator for evaluation though
>
>   echo echo a                  => "echo a"
>    (echo echo a)                => "echo a"
>   ((echo echo a))              => "a"
>   (((echo echo a)))           => "a"
>   ((((echo echo a))))         => command not found
>   (echo (echo echo a))     => "echo a"
>   (echo ((echo echo a)))   => "a"
>   ((echo (echo echo a)))   => "a"
>   ((echo ((echo echo a)))) => command not found
>
> If we want () to be evaluating the content, we can't use it for grouping
> without evaluating ...
> In addition this syntax looks quite ugly ...
>
> So I'd rather have ( ... ) for pure grouping and $( ... ) for evaluating as
> we have in bash.
>
>
>
> On Tue, Aug 11, 2009 at 23:27, Derek Baum <derek.b...@paremus.com> wrote:
>
> > 2009/8/11 Guillaume Nodet <gno...@gmail.com>
> >
> > > I'd like to tackle this issue but I'm still not comfortable at the
> > meaning
> > > of $() and ().
> >
> >
> > I think I may have complicated this issue by introducing $().
> > I no longer think $() is needed.
> > I think we can change <> directly to () without changing their semantics.
> >
> >
> >
> > >
> > > The problem I have is whether the output should be evaluated or not.
> >
> >
> >
> > The output i.e. stdout should not be evaluated. If we need to do capture
> it
> > RFC132 proposes a 'tac' command.
> > The first word after opening ( should be treated as a command and cause a
> > failure if the command is not found.
> >
> >
> >
> > >
> > > For example, if we consider () to be equivalent to <>
> > >
> > >  echo a          => "a"
> > >  echo echo a     => "echo a"
> > >  echo a ; echo b => "ab"
> > >
> > > Now, when using parenthesis, we have the following options
> > >
> > >  (echo echo a)   => "a"  or "echo a"
> > >
> > > I think it should be "echo a", else we can't really use it for grouping
> > > commands for piping:
> >
> >
> >
> > yes, I agree.
> >
> >
> >
> > >
> > >
> > >  e = { echo $0 } ; (e a   b | capture)
> > >
> > > This would fail because "e a  b" would be evaluated to "a", then
> capture,
> > > but the resulting value is not a command, so a command not found
> > exception
> > > would be thrown.
> > >
> > > I think it would be more intuitive for the evaluation to be the
> > > differenciator between () and $().
> > > So we'd have:
> > >
> > >  echo echo a     => "echo a"
> >
> > agree.
> >
> > >
> > >  (echo echo a)   => "echo a"
> >
> > agree.
> >
> > >
> > >  ((echo echo a)) => "echo a"
> >
> >
> > I think this should fail with command not found: a
> >
> > If the inner evaluation is not intended to produce a command:
> >
> > (echo result: (echo echo a)) => result: a
>
>
> Did you mean "result: echo a" as the output ?
>
> >
> >
> > The Unix analog (which also fails) is:
> >
> > bash% $($(echo echo a))
> > -bash: a: command not found
> >
> >
> >
> > >
> > >  $(echo echo a)  => "a"
> >
> >
> > This is equivalent to (echo echo a | tac)
> >
> > At first I liked the idea of removing 'tac' and replacing it with $() -
> but
> > 'tac' is actually more flexible:
> >
> > e.g. write to file as RFC132 doesn't provide Unix-like IO redirection:
> >
> > bundles | tac -f b.txt
> >
> > I have also found it useful to add 'tac --list' that returns the output
> as
> > a
> > list, rather than a String, as this can then be iterated over using each:
> >
> > each <bundles | grep felix> { echo felix bundle: $it }
> >
> > Derek
> >
> >
> > >
> > >
> > > Thoughts ?
> > >
> > > On Wed, Jul 22, 2009 at 12:43, Hiram Chirino<chir...@gmail.com> wrote:
> > > > On Fri, Jul 17, 2009 at 7:25 AM, Derek Baum <derek.b...@paremus.com>
> > > wrote:
> > > >
> > > >> In RFC132, although <> are compared to shell backquotes, there are
> > > actually
> > > >> just executing the command,
> > > >> and not capturing its output as done by shell backquotes, so I agree
> > > that
> > > >> <>
> > > >> should become () and not $().
> > > >>
> > > >> Some background to help clarify:
> > > >>
> > > >> In Unix shells, parenthesis () are used to run commands in a
> subshell,
> > > so
> > > >> for example, all output goes to the pipe:
> > > >>
> > > >> $ echo one; echo two | nl
> > > >> one
> > > >>     1  two
> > > >>
> > > >> $ (echo one; echo two) | nl
> > > >>     1  one
> > > >>     2  two
> > > >>
> > > >> $() is the modern equivalent of backquotes `` in Unix shells, and
> can
> > be
> > > >> nested.
> > > >>
> > > >> It is also logical: () runs a group of commands and $() captures the
> > > result
> > > >> as a string:
> > > >>
> > > >> $ hg paths default
> > > >> ssh://h...@hg.paremus.com:24/posh
> > > >> $ project=$(basename $(hg paths default))
> > > >> $ echo $project
> > > >> posh
> > > >>
> > > >> However in RFC132, we rarely need to capture output as strings - we
> > can
> > > use
> > > >> the returned objects directly,
> > > >> so the above could look like this in RFC132:
> > > >>
> > > >> > project = (basename (hg paths default))
> > > >>
> > > >> or if 'hg paths default' returned a File object:
> > > >>
> > > >> > project = (hg paths default) getName
> > > >>
> > > >>
> > > >> Shell backquotes are similar to the 'tac' command in RFC132, which
> > > captures
> > > >> the output of a command and returns it as a string:
> > > >>
> > > >> assuming grep prints to stdout and returns boolean to indicate
> whether
> > > it
> > > >> found a match:
> > > >>
> > > >> This sets b to the boolean result of grep:
> > > >>
> > > >> % b = <bundles | grep felix>
> > > >> 000000 ACT org.apache.felix.framework-1.8.1
> > > >> % echo $b
> > > >> true
> > > >>
> > > >> We can use tac to capture the output of grep as a string:
> > > >>
> > > >> % b = <bundles | grep felix | tac>
> > > >> % echo $b
> > > >> 000000 ACT org.apache.felix.framework-1.8.1true
> > > >>
> > > >> We _could_ instead define $() to capture output, as it does in Unix:
> > > >>
> > > >> % b = $(bundles | grep felix)
> > > >>
> > > >> Derek
> > > >>
> > > >
> > > > +1.  The fact of the matter is the 'casual' users of the shell will
> NOT
> > > be
> > > > aware of the more powerful underlying type system that is available
> via
> > > > arguments and return types.  These users will prefer to work with
> > stdout
> > > > results since it's output is 'self-documenting'.  Support for
> > constructs
> > > > like $(...) will make these kinds of user's lives easier.
> > > >
> > > >
> > > >
> > > >>
> > > >>
> > > >>
> > > >>
> > > >> 2009/7/17 Peter Kriens <peter.kri...@aqute.biz>
> > > >>
> > > >> > I am not sure I see why we need $( ... ) for evaluation, instead
> of
> > (
> > > ...
> > > >> > )?
> > > >> >
> > > >> > Kind regards,
> > > >> >
> > > >> >        Peter Kriens
> > > >> >
> > > >> >
> > > >> >
> > > >> >
> > > >> >
> > > >> > On 16 jul 2009, at 16:22, Derek Baum wrote:
> > > >> >
> > > >> >  2009/7/16 Peter Kriens <peter.kri...@aqute.biz>
> > > >> >>
> > > >> >>
> > > >> >>> I do agree that we should replace the <> with (). This makes a
> lot
> > > of
> > > >> >>> sense
> > > >> >>> and there are not that many filters in use anyway. We could now
> > make
> > > >> >>> filters
> > > >> >>> <> if we want.
> > > >> >>>
> > > >> >>> [snip]
> > > >> >>>
> > > >> >>> About the priority of | and ; ... I remember thinking long and
> > hard
> > > >> about
> > > >> >>> this but forgot why I picked this model, it still seems slightly
> > > more
> > > >> >>> powerful because the newline acts as a ';' with a higher
> priority
> > > than
> > > >> >>> the
> > > >> >>> '|' but I am not opposed to switching the priority.
> > > >> >>>
> > > >> >>
> > > >> >>
> > > >> >> if we agree to use $() for command execution instead of <>
> > > >> >> then we can use () for command grouping, and thus the examples
> > below
> > > >> would
> > > >> >> work the same in Unix or RFC132 shell:
> > > >> >>
> > > >> >> echo a; echo b | cat
> > > >> >> (echo a; echo b) | cat
> > > >> >>
> > > >> >> We could also add a converter to coerce a string into an LDAP
> > filter
> > > to
> > > >> >> make
> > > >> >> up for stealing the ().
> > > >> >>
> > > >> >>
> > > >> >>
> > > >> >>  I am not sure about throwing an error when a command is not
> > > recognized.
> > > >> >>> Using its value seems sufficient to me and has some advantages.
> I
> > do
> > > >> not
> > > >> >>> think this would ever confuse me.
> > > >> >>>
> > > >> >>
> > > >> >>
> > > >> >> It has already confused users on Karaf :-)
> > > >> >>
> > > >> >> A 'command not found' error only occurs if you pass an argument
> to
> > an
> > > >> >> unknown command, otherwise it silently evaluates to itself.
> > > >> >>
> > > >> >> Although this may be apparent to a user at the console, it would
> be
> > > much
> > > >> >> more difficult to diagnose in a script containing a mis-spelled
> > > command.
> > > >> >>
> > > >> >> I have attached a simple patch to experiment with this to
> > > >> >> https://issues.apache.org/jira/browse/FELIX-1325
> > > >> >>
> > > >> >> This patch simply avoids re-evaluating a single argument to an
> > > >> assignment,
> > > >> >> so
> > > >> >>
> > > >> >> x = hello
> > > >> >>
> > > >> >> works as before, but when evaluated in a non-assignment context,
> it
> > > >> fails
> > > >> >> if
> > > >> >> a 'hello' command is not found.
> > > >> >>
> > > >> >> Variable expansion using ${ab} rather than $ab is still
> > problematic.
> > > >> >>
> > > >> >> the ${ab} notation is in common usage:
> > > >> >>
> > > >> >>  - Unix allows it to delimit the variable name from following
> text
> > > >> >>  - Many Java programs interpret ${xx} as expansion of system
> > > properties
> > > >> >>
> > > >> >> It also works in the RFC132 shell, but in this case {ab} defines
> a
> > > >> closure
> > > >> >> and the $ evaulates it.
> > > >> >>
> > > >> >> If you really wanted to capture the result of executing ab, then
> > <ab>
> > > or
> > > >> >> our
> > > >> >> proposed $(ab) is the way to go.
> > > >> >>
> > > >> >> This would then allow us to interpret ${ab}, according to its
> comon
> > > >> usage
> > > >> >> -
> > > >> >> enhanced variable expansion.
> > > >> >> We could also usefully add the Unix variable expansion:
> > > ${var:-default}
> > > >> >>
> > > >> >> Derek
> > > >> >>
> > > >> >>
> > > >> >>
> > > >> >>>
> > > >> >>> Nice to get some discussion going! However, please note that
> this
> > is
> > > an
> > > >> >>> OSGi RFC. I will update the RFC in the coming weeks and discuss
> it
> > > in
> > > >> >>> CPEG.
> > > >> >>> I hope to schedule it then for inclusion in an upcoming
> > compendium.
> > > >> >>>
> > > >> >>> I'd like to add one more thing. In Blueprint we spent a lot of
> > time
> > > on
> > > >> >>> type
> > > >> >>> conversion and I like very much what we got there. I think it
> > would
> > > be
> > > >> a
> > > >> >>> good idea to use the same type converters, especially because
> they
> > > also
> > > >> >>> handle generics when available.
> > > >> >>>
> > > >> >>
> > > >> >>
> > > >> >>
> > > >> >>> Kind regards,
> > > >> >>>
> > > >> >>>      Peter Kriens
> > > >> >>>
> > > >> >>>
> > > >> >>>
> > > >> >
> > > >>
> > > >
> > > >
> > > >
> > > > --
> > > > Regards,
> > > > Hiram
> > > >
> > > > Blog: http://hiramchirino.com
> > > >
> > > > Open Source SOA
> > > > http://fusesource.com/
> > > >
> > >
> > >
> > >
> > > --
> > > Cheers,
> > > Guillaume Nodet
> > > ------------------------
> > > Blog: http://gnodet.blogspot.com/
> > > ------------------------
> > > Open Source SOA
> > > http://fusesource.com
> > >
> >
>
>
>
> --
> Cheers,
> Guillaume Nodet
> ------------------------
> Blog: http://gnodet.blogspot.com/
> ------------------------
> Open Source SOA
> http://fusesource.com
>

Reply via email to