Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

computed goto

338 views
Skip to first unread message

zermelo

unread,
Aug 10, 2012, 7:33:57 AM8/10/12
to

I need to code something like this:
(let ((n 2))
(tagbody
(go n)
1 (print 1)
2 (print 2)))
=> expected 2

Is there a way I can pass an expression to the go form?

Thanks
Ps
I don’t need a ‘goto considered harmful’ sermon :)

Pascal J. Bourguignon

unread,
Aug 10, 2012, 8:53:31 AM8/10/12
to
(defmacro computed-tagbody (&body body)
(let ((tags (remove-if-not (lambda (tag) (or (symbolp tag) (integerp tag))) body)))
`(macrolet ((goto (expression)
`(ecase ,expression
,@(mapcar (lambda (tag) `((,tag) (go ,tag))) ',tags))))
(tagbody
,@body))))

(loop :repeat 10
:do (computed-tagbody
(goto (random 3))
0 (print 0) (go :end)
1 (print 1) (go :end)
2 (print 2) (go :end)
:end))

2
0
2
1
2
0
1
0
0
2 nil

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

Bernd Nawothnig

unread,
Aug 10, 2012, 8:55:38 AM8/10/12
to
On 2012-08-10, zermelo wrote:
>
> I need to code something like this:
> (let ((n 2))
> (tagbody
> (go n)
> 1 (print 1)
> 2 (print 2)))
>=> expected 2
>
> Is there a way I can pass an expression to the go form?

(let ((n 2)) (print (cond ((= n 1) 1) ((= n 2) 2))))

> Thanks
> Ps
> I don’t need a ‘goto considered harmful’ sermon :)

It may not be harmful. But it is ugly und completely unnecessary.

And if you don't like the functional approach you should better
consider not to use a functional language.



Bernd

--
"Die Antisemiten vergeben es den Juden nicht, dass die Juden Geist
haben - und Geld." [Friedrich Nietzsche]

Zach Beane

unread,
Aug 10, 2012, 8:58:23 AM8/10/12
to
Bernd Nawothnig <Bernd.N...@t-online.de> writes:

> And if you don't like the functional approach you should better
> consider not to use a functional language.

Fortunately, Common Lisp is not a functional language.

Zach

Frank DG1SBG

unread,
Aug 10, 2012, 9:07:31 AM8/10/12
to
Ahem - like this?

(defun print-value (value)
(format *debug-io* "Value is ~s.~&" value))

(defun jump-on-value (value)
(cond
((= value 1)
(format *debug-io* "~%Hi there in 1.~&")
(print-value value))
((= value 2)
(format *debug-io* "~%Hi there in 2.~&")
(print-value value))))

I'm pretty sure this isn't what you were looking for. So - what are you
looking for?

Frank

Pascal J. Bourguignon

unread,
Aug 10, 2012, 9:19:23 AM8/10/12
to
"Pascal J. Bourguignon" <p...@informatimago.com> writes:

> zermelo <zer...@nospam.teletu.it> writes:
>
>> I need to code something like this:
>> (let ((n 2))
>> (tagbody
>> (go n)
>> 1 (print 1)
>> 2 (print 2)))
>> => expected 2
>>
>> Is there a way I can pass an expression to the go form?
>>
>> Thanks
>> Ps
>> I don’t need a ‘goto considered harmful’ sermon :)
>
> (defmacro computed-tagbody (&body body)
> (let ((tags (remove-if-not (lambda (tag) (or (symbolp tag) (integerp tag))) body)))
> `(macrolet ((goto (expression)
> `(ecase ,expression
> ,@(mapcar (lambda (tag) `((,tag) (go ,tag))) ',tags))))
> (tagbody
> ,@body))))

Exercise left to the reader: implement a computed-comefrom operator! :-)

zermelo

unread,
Aug 10, 2012, 9:47:11 AM8/10/12
to
@Pascal
Thanks. Now I go and study your solution.

@others
The silly example in the post was provided only to explain the
concept of “computed goto”, that after decades of witch-hunt is
unfortunately alien to most of programmers minds. Really I don’t need a
goto-free print-a-number code snippet.

Anyway thanks for your pedagogical cares.

Bernd Nawothnig

unread,
Aug 10, 2012, 9:53:44 AM8/10/12
to
Nope.

Lisp is not solely a functional language, but it is more functional
than most other languages. And because of that Wikipedia lists Common
Lisp as a functional language:

http://en.wikipedia.org/wiki/Functional_programming

Pascal J. Bourguignon

unread,
Aug 10, 2012, 10:32:55 AM8/10/12
to
"Pascal J. Bourguignon" <p...@informatimago.com> writes:

> "Pascal J. Bourguignon" <p...@informatimago.com> writes:
>
>> zermelo <zer...@nospam.teletu.it> writes:
>>
>>> I need to code something like this:
>>> (let ((n 2))
>>> (tagbody
>>> (go n)
>>> 1 (print 1)
>>> 2 (print 2)))
>>> => expected 2
>>>
>>> Is there a way I can pass an expression to the go form?
>>>
>>> Thanks
>>> Ps
>>> I don’t need a ‘goto considered harmful’ sermon :)
>>
>> (defmacro computed-tagbody (&body body)
>> (let ((tags (remove-if-not (lambda (tag) (or (symbolp tag) (integerp tag))) body)))
>> `(macrolet ((goto (expression)
>> `(ecase ,expression
>> ,@(mapcar (lambda (tag) `((,tag) (go ,tag))) ',tags))))
>> (tagbody
>> ,@body))))
>
> Exercise left to the reader: implement a computed-comefrom operator! :-)

Solution:

(defmacro comefrom-tagbody (&body body)
"
DO: Implement the COMEFROM control structure:

EXAMPLE:
(comefrom-tagbody
:start
(print 'hi)
:next
(print 'lo)
(comefrom :next)
(print 'one)
(go :end)
(comefrom :next)
(print 'two)
:end)

prints:
HI
ONE
or prints:
HI
TWO
and returns:
NIL

Note: The COMEFROM forms can only be written on the
toplevel of the BODY.

"
(let* ((cftags (make-hash-table))
(newbody (loop
:named first-collect-comefroms
:with newbody = '()

:for item :in body
:do (if (and (consp item) (eq 'comefrom (car item)))
(let ((newtag (gensym)))
(push newtag newbody)
(push newtag (gethash (second item) cftags '())))
(push item newbody))
:finally (return-from first-collect-comefroms (nreverse newbody))))
(finalbody (loop
:named add-the-go-from-the-tags
:with finalbody = '()
:for item :in newbody
:do (let ((cf (gethash item cftags)))
(push item finalbody)
(when cf
(if (cdr cf)
;; more than one comefrom this tag! Let's choose randomly
(push `(case (random ,(length cf))
,@(let ((i -1)) (mapcar (lambda (tag)
`((,(incf i)) (go ,tag)))
cf)))
finalbody)
;; a single comefrom
(push `(go (car cf)) finalbody))))
:finally (return-from add-the-go-from-the-tags (nreverse finalbody)))))
`(macrolet ((comefrom (tag) `(error "~S can only be used at the toplevel of the COMEFROM-TAGBODY body."'comefrom)))
(tagbody
,@finalbody))))




(let ((i 0))
(comefrom-tagbody

(comefrom :end-loop)
(if (< i 5) (go :print))
:test-done

:print
(print (incf i))
:end-loop

(comefrom :test-done)
(print 'done)
(terpri)))

prints:
1
2
3
4
5
done
--> nil



(comefrom-tagbody
:start
(print 'hi)
:next
(print 'lo)
(comefrom :next)
(print 'one)
(go :end)
(comefrom :next)
(print 'two)
:end
(terpri))

prints:
hi
two
--> nil
or:
hi
one
--> nil


As can be seen, not having comefrom inside subforms of the body is a big
inconvenient, since it means we have to use GO too. Exercise left to
the reader: modify the macro to be able to come from, and come into
inside subforms, so that we can write:

(let ((i 0))
(comefrom-tagbody

(comefrom :end-loop)
(if (>= i 5)
:done)

(print (incf i))
:end-loop

(comefrom :done)
(print 'done)
(terpri)))

prints:
1
2
3
4
5
done
--> nil

What would:

(let ((i 0))
(comefrom-tagbody

(comefrom :end-loop)
(if (>= i 5)
:done)

(print (incf i))
:end-loop

(if (zerop (random 2))
(comefrom 5))

(print 'done)
(terpri)))

do?

Zermelo

unread,
Aug 10, 2012, 12:09:05 PM8/10/12
to
Using Clozure CL with this code

(let ((i 0))
(comefrom-tagbody

(comefrom :end-loop)
(if (>= i 5)
:done)

(print (incf i))
:end-loop

(if (zerop (random 2))
(comefrom 5))

(print 'done)
(terpri)))

I get this error:
While compiling an anonymous function :
Can't GO to tag (CAR CF).
[Condition of type CCL::COMPILE-TIME-PROGRAM-ERROR]

Pascal Costanza

unread,
Aug 10, 2012, 12:16:54 PM8/10/12
to
On 10/08/2012 15:53, Bernd Nawothnig wrote:
> On 2012-08-10, Zach Beane wrote:
>> Bernd Nawothnig <Bernd.N...@t-online.de> writes:
>>
>>> And if you don't like the functional approach you should better
>>> consider not to use a functional language.
>>
>> Fortunately, Common Lisp is not a functional language.
>
> Nope.
>
> Lisp is not solely a functional language, but it is more functional
> than most other languages. And because of that Wikipedia lists Common
> Lisp as a functional language:
>
> http://en.wikipedia.org/wiki/Functional_programming

Common Lisp doesn't impose a particular programming style on its users.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
The views expressed are my own, and not those of my employer.

Pascal J. Bourguignon

unread,
Aug 10, 2012, 12:43:01 PM8/10/12
to
Zermelo <zer...@teletu.it.nospam.invalid> writes:

> Using Clozure CL with this code
> I get this error:
> While compiling an anonymous function :
> Can't GO to tag (CAR CF).
> [Condition of type CCL::COMPILE-TIME-PROGRAM-ERROR]

I forgot to update the copy in gnus. Add a comma before (car cf) in (go
(car cf)).

Zermelo

unread,
Aug 10, 2012, 3:04:26 PM8/10/12
to
Ok, thanks.

Bernd Nawothnig

unread,
Aug 11, 2012, 5:01:52 AM8/11/12
to
On 2012-08-10, Pascal Costanza wrote:
> On 10/08/2012 15:53, Bernd Nawothnig wrote:
>> On 2012-08-10, Zach Beane wrote:
>>> Bernd Nawothnig <Bernd.N...@t-online.de> writes:
>>>
>>>> And if you don't like the functional approach you should better
>>>> consider not to use a functional language.
>>>
>>> Fortunately, Common Lisp is not a functional language.
>>
>> Nope.
>>
>> Lisp is not solely a functional language, but it is more functional
>> than most other languages. And because of that Wikipedia lists Common
>> Lisp as a functional language:
>>
>> http://en.wikipedia.org/wiki/Functional_programming
>
> Common Lisp doesn't impose a particular programming style on its users.

Even if a language does not impose a certain style that does not mean
that this language is equally suitable for all puposes and all styles.

If somebody thinks he needs a goto he should better use a language
which already comes with that construct (like C/C++). C/C++ supports
imperative programming style much better than a language which
originated from the lambda calculus. And the simple question for a
goto shows clearly that the poster likes imperative programming style.

If you really need a hammer you should better use a hammer and not
something that may be up to some extent also usable for that purpose.

Pascal Costanza

unread,
Aug 11, 2012, 5:46:04 AM8/11/12
to
On 11/08/2012 11:01, Bernd Nawothnig wrote:
> On 2012-08-10, Pascal Costanza wrote:
>> On 10/08/2012 15:53, Bernd Nawothnig wrote:
>>> On 2012-08-10, Zach Beane wrote:
>>>> Bernd Nawothnig <Bernd.N...@t-online.de> writes:
>>>>
>>>>> And if you don't like the functional approach you should better
>>>>> consider not to use a functional language.
>>>>
>>>> Fortunately, Common Lisp is not a functional language.
>>>
>>> Nope.
>>>
>>> Lisp is not solely a functional language, but it is more functional
>>> than most other languages. And because of that Wikipedia lists Common
>>> Lisp as a functional language:
>>>
>>> http://en.wikipedia.org/wiki/Functional_programming
>>
>> Common Lisp doesn't impose a particular programming style on its users.
>
> Even if a language does not impose a certain style that does not mean
> that this language is equally suitable for all puposes and all styles.

This is wrong. Common Lisp is equally suitable for all purposes and all
styles.

> If somebody thinks he needs a goto he should better use a language
> which already comes with that construct (like C/C++). C/C++ supports
> imperative programming style much better than a language which
> originated from the lambda calculus. And the simple question for a
> goto shows clearly that the poster likes imperative programming style.

This is also wrong. Just because you want to use goto in some parts of a
program doesn't mean you have to throw away all the other useful
features that you want to use in other parts of the same program. That's
the very essence of a multi-paradigm programming language.

> If you really need a hammer you should better use a hammer and not
> something that may be up to some extent also usable for that purpose.

This is again wrong. Common Lisp is not a hammer, Common Lisp is a toolbox.

Bernd Nawothnig

unread,
Aug 11, 2012, 6:15:30 AM8/11/12
to
On 2012-08-11, Pascal Costanza wrote:
> On 11/08/2012 11:01, Bernd Nawothnig wrote:
>> On 2012-08-10, Pascal Costanza wrote:
>>> On 10/08/2012 15:53, Bernd Nawothnig wrote:
>>>> On 2012-08-10, Zach Beane wrote:
>>>>> Bernd Nawothnig <Bernd.N...@t-online.de> writes:
>>>>>
>>>>>> And if you don't like the functional approach you should better
>>>>>> consider not to use a functional language.
>>>>>
>>>>> Fortunately, Common Lisp is not a functional language.
>>>>
>>>> Nope.
>>>>
>>>> Lisp is not solely a functional language, but it is more functional
>>>> than most other languages. And because of that Wikipedia lists Common
>>>> Lisp as a functional language:
>>>>
>>>> http://en.wikipedia.org/wiki/Functional_programming
>>>
>>> Common Lisp doesn't impose a particular programming style on its users.
>>
>> Even if a language does not impose a certain style that does not mean
>> that this language is equally suitable for all puposes and all styles.
>
> This is wrong. Common Lisp is equally suitable for all purposes and all
> styles.

Your opinion ...

>> If somebody thinks he needs a goto he should better use a language
>> which already comes with that construct (like C/C++). C/C++ supports
>> imperative programming style much better than a language which
>> originated from the lambda calculus. And the simple question for a
>> goto shows clearly that the poster likes imperative programming style.
>
> This is also wrong. Just because you want to use goto in some parts of a
> program doesn't mean you have to throw away all the other useful
> features that you want to use in other parts of the same program. That's
> the very essence of a multi-paradigm programming language.

Many languages claim to be multi-paradigm, C/C++ e.g.. If that is
true, there would be no reason, to stuck especially with Lisp
because C/C++ would offer exactly the same benefits. And C/C++ already
comes with a builtin goto.

Some people claim even C and Assembler to be suitable for OOP ...

>> If you really need a hammer you should better use a hammer and not
>> something that may be up to some extent also usable for that purpose.
>
> This is again wrong. Common Lisp is not a hammer, Common Lisp is a toolbox.

The hammer would be a language which already provides what he was
looking for.

Pascal Costanza

unread,
Aug 11, 2012, 7:06:45 AM8/11/12
to
On 11/08/2012 12:15, Bernd Nawothnig wrote:
> On 2012-08-11, Pascal Costanza wrote:
>> On 11/08/2012 11:01, Bernd Nawothnig wrote:
>>> On 2012-08-10, Pascal Costanza wrote:
>>>> On 10/08/2012 15:53, Bernd Nawothnig wrote:
>>>>> On 2012-08-10, Zach Beane wrote:
>>>>>> Bernd Nawothnig <Bernd.N...@t-online.de> writes:
>>>>>>
>>>>>>> And if you don't like the functional approach you should better
>>>>>>> consider not to use a functional language.
>>>>>>
>>>>>> Fortunately, Common Lisp is not a functional language.
>>>>>
>>>>> Nope.
>>>>>
>>>>> Lisp is not solely a functional language, but it is more functional
>>>>> than most other languages. And because of that Wikipedia lists Common
>>>>> Lisp as a functional language:
>>>>>
>>>>> http://en.wikipedia.org/wiki/Functional_programming
>>>>
>>>> Common Lisp doesn't impose a particular programming style on its users.
>>>
>>> Even if a language does not impose a certain style that does not mean
>>> that this language is equally suitable for all puposes and all styles.
>>
>> This is wrong. Common Lisp is equally suitable for all purposes and all
>> styles.
>
> Your opinion ...

Ah, it's good that we finally agree that it's a matter of opinion, not a
matter of absolute truth.

>>> If somebody thinks he needs a goto he should better use a language
>>> which already comes with that construct (like C/C++). C/C++ supports
>>> imperative programming style much better than a language which
>>> originated from the lambda calculus. And the simple question for a
>>> goto shows clearly that the poster likes imperative programming style.
>>
>> This is also wrong. Just because you want to use goto in some parts of a
>> program doesn't mean you have to throw away all the other useful
>> features that you want to use in other parts of the same program. That's
>> the very essence of a multi-paradigm programming language.
>
> Many languages claim to be multi-paradigm, C/C++ e.g.. If that is
> true, there would be no reason, to stuck especially with Lisp
> because C/C++ would offer exactly the same benefits. And C/C++ already
> comes with a builtin goto.

There would also be no reason to stick especially with C/C++, because
Lisp offers exactly the same benefits. And Lisp also already comes with
a built-in goto. [1]

I recommend to you to read a bit about the history and accounts of Lisp
over the decades, the notion that Lisp and its dialects are really
supposed to be used for a wide range of programming styles is really
common place among Lispers - not only not to be afraid to use the
different styles, but actively embrace them.

"If you give someone Fortran, he has Fortran.
If you give someone Lisp, he has any language he pleases."
- Guy L. Steele

...just one of many similar "opinions."


Pascal

[1] It's actually one of the built-in special operators. See
http://www.lispworks.com/documentation/HyperSpec/Body/03_ababa.htm

Pascal J. Bourguignon

unread,
Aug 11, 2012, 8:23:19 AM8/11/12
to
Bernd Nawothnig <Bernd.N...@t-online.de> writes:

> Many languages claim to be multi-paradigm, C/C++ e.g.. If that is
> true, there would be no reason, to stuck especially with Lisp
> because C/C++ would offer exactly the same benefits. And C/C++ already
> comes with a builtin goto.

Both C++ and Lisp are multi-paradigm. But Lisp is a much better
multi-paradigm programming language than C++.


> Some people claim even C and Assembler to be suitable for OOP ...

Indeed, they're perfectly usable to do OO, notably with a few macro, or
a light pre-processor, such as Objective-C :-)

Zermelo

unread,
Aug 11, 2012, 9:53:13 AM8/11/12
to
Bernd Nawothnig <Bernd.N...@t-online.de> writes:

>
> If somebody thinks he needs a goto he should better use a language
> which already comes with that construct (like C/C++). C/C++ supports
> imperative programming style much better than a language which
> originated from the lambda calculus. And the simple question for a
> goto shows clearly that the poster likes imperative programming style.
>

C/C++ doesn’t have a native computed goto. The only way I know to
simulate it is to use a switch/case.

What I really like of Lisp is that it doesn’t impose a style: even if it
doesn’t have a feature, you can easily implement it, as Pascal’s code
has demonstrated.

I came to Lisp because I like functional programming and the way you can
straightforwardly express your ideas. But not every problem is equally
well suited to FP. Sometimes you just need a damn goto :)

Bernd Nawothnig

unread,
Aug 11, 2012, 12:16:07 PM8/11/12
to
On 2012-08-11, Zermelo wrote:
> C/C++ doesn’t have a native computed goto. The only way I know to
> simulate it is to use a switch/case.

Yeah, but switch/case results in jumping to blocks of code depending
on the value of the switch variable. And that is exactly what a
computed goto does.

> What I really like of Lisp is that it doesn’t impose a style: even if it
> doesn’t have a feature, you can easily implement it, as Pascal’s code
> has demonstrated.

And C has it's macro processor with which you can do a lot. But is all
that really an advantage? Does it help to make the code better
understandable? I personally doubt that - and I'm not alone with that
opinion. If a language allows too much it will result in thousands of
ways to code a solution and in unnecessary difficulties to understand
foreign code. Some sort of restriction and "guidance" (not too much,
of course) is IMO necessary. Python is a good example for that. Guido
always keeps an eye on the core language to be as simple and small as
possible.

> I came to Lisp because I like functional programming and the way you
> can straightforwardly express your ideas.

Yeah, exactly.

> But not every problem is equally well suited to FP.

Sure, Haskell has its monads for these cases.

> Sometimes you just need a damn goto :)

You never need a goto, believe me. You only may *think* sometimes you
need one ;-)

Bill

unread,
Aug 11, 2012, 12:42:27 PM8/11/12
to
> C/C++ doesn’t have a native computed goto.

gnu c does, but in my experience it is not much, if any,
faster than a switch statement.

Bernd Nawothnig

unread,
Aug 11, 2012, 12:49:56 PM8/11/12
to
On 2012-08-11, Pascal Costanza wrote:
>>>> Even if a language does not impose a certain style that does not mean
>>>> that this language is equally suitable for all puposes and all styles.
>>>
>>> This is wrong. Common Lisp is equally suitable for all purposes and all
>>> styles.
>>
>> Your opinion ...
>
> Ah, it's good that we finally agree that it's a matter of opinion, not a
> matter of absolute truth.

Exactly.

[...]

> "If you give someone Fortran, he has Fortran.
> If you give someone Lisp, he has any language he pleases."
> - Guy L. Steele
>
> ...just one of many similar "opinions."

Compared with FORTRAN almost every language looks nice and bright ;-)

RG

unread,
Aug 11, 2012, 2:25:59 PM8/11/12
to
In article <46551c33-9db1-49e6...@googlegroups.com>,
That's because a switch statement compiles to a computed goto.

rg

RG

unread,
Aug 11, 2012, 2:28:47 PM8/11/12
to
In article <85boih3...@teletu.it.nospam.invalid>,
Zermelo <zer...@teletu.it.nospam.invalid> wrote:

> Bernd Nawothnig <Bernd.N...@t-online.de> writes:
>
> >
> > If somebody thinks he needs a goto he should better use a language
> > which already comes with that construct (like C/C++). C/C++ supports
> > imperative programming style much better than a language which
> > originated from the lambda calculus. And the simple question for a
> > goto shows clearly that the poster likes imperative programming style.
> >
>
> C/C++ doesn’t have a native computed goto. The only way I know to
> simulate it is to use a switch/case.

You can also make an array of function pointers and do:

*array[index]()

(Or something like that. My pointer-to-function-fu is rusty.)

This is the best you can hope to do in any language that hides (or tries
to hide) the fact that code is actually addressable by integers.

rg

Bernd Nawothnig

unread,
Aug 11, 2012, 2:52:29 PM8/11/12
to
On 2012-08-11, Pascal J. Bourguignon wrote:
> Bernd Nawothnig <Bernd.N...@t-online.de> writes:
>
>> Many languages claim to be multi-paradigm, C/C++ e.g.. If that is
>> true, there would be no reason, to stuck especially with Lisp
>> because C/C++ would offer exactly the same benefits. And C/C++ already
>> comes with a builtin goto.
>
> Both C++ and Lisp are multi-paradigm. But Lisp is a much better
> multi-paradigm programming language than C++.

You can be very sure that I would get another answer for the same
question in the C++ group ;-)

>> Some people claim even C and Assembler to be suitable for OOP ...
>
> Indeed, they're perfectly usable to do OO, notably with a few macro, or
> a light pre-processor, such as Objective-C :-)

Yeah, back to the roots ;-)

Frode V. Fjeld

unread,
Aug 11, 2012, 3:00:37 PM8/11/12
to
Bernd Nawothnig <Bernd.N...@t-online.de> writes:

> If somebody thinks he needs a goto he should better use a language
> which already comes with that construct (like C/C++).

As does Common Lisp, so what is your point?

--
Frode V. Fjeld

Zermelo

unread,
Aug 11, 2012, 3:02:37 PM8/11/12
to
RG <rNOS...@flownet.com> writes:

> You can also make an array of function pointers and do:
>
> *array[index]()

This is a nice trick, but you cannot jump inside another scope in this
way.
E.g. you cannot write code like this

<my goto-substitute with function pointers> label1;
<stuff...>
while (test) {
label1:
<other stuff>
}

Helmut Eller

unread,
Aug 11, 2012, 3:06:36 PM8/11/12
to
Well, a switch statement needs to perform a range check first, then look
up the address in a table, then perform the computed goto. Computed
gotos should be a win if the indirection through the table can be
avoided.

Helmut

Pascal J. Bourguignon

unread,
Aug 11, 2012, 3:19:55 PM8/11/12
to
That's ludicruous! In a language where the Duff device is valid,
there's no reason to prevent jumping into or out of loops.

Duff device:

send(to, from, count)
register short *to, *from;
register count;
{
register n = (count + 7) / 8;
switch(count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while(--n > 0);
}
}

What an horror! (But there's no difference between this code and yours).

Bernd Nawothnig

unread,
Aug 11, 2012, 3:27:06 PM8/11/12
to
On 2012-08-11, Helmut Eller wrote:
> On Sat, Aug 11 2012, RG wrote:
>
>> In article <46551c33-9db1-49e6...@googlegroups.com>,
>> Bill <schott...@gmail.com> wrote:
>>
>>> > C/C++ doesn t have a native computed goto.
>>>
>>> gnu c does, but in my experience it is not much, if any,
>>> faster than a switch statement.
>>
>> That's because a switch statement compiles to a computed goto.
>
> Well, a switch statement needs to perform a range check first, then look
> up the address in a table, then perform the computed goto.

Not necessarily. The compiler knows all case constants and if they are
close enough a table of addresses is generated and only one
range-check at the beginning is needed. And if it is a byte-variable
even that check can be omitted. As far as I know uses the Python
runtime interpreter when compiled with a newer gcc this feature for a
significant speed up when switching by the byte-opcode.

> Computed gotos should be a win if the indirection through the table
> can be avoided.

Depends on the CPU and cache size how much that indirection costs. For
modern CPUs it should be neglectable.

Bernd Nawothnig

unread,
Aug 11, 2012, 3:37:59 PM8/11/12
to
On 2012-08-11, Pascal J. Bourguignon wrote:
Yeah, that is a jump into the do-while-loop. But what will happen if
there are local variables declared inside the loop?

> What an horror!

Indeed. A very ugly example for source code optimization. I think
(hope) modern compilers will do the above automatically (which should
be possible).

> (But there's no difference between this code and yours).

Correct.

Helmut Eller

unread,
Aug 12, 2012, 2:44:07 AM8/12/12
to
On Sat, Aug 11 2012, Bernd Nawothnig wrote:

>> Computed gotos should be a win if the indirection through the table
>> can be avoided.
>
> Depends on the CPU and cache size how much that indirection costs. For
> modern CPUs it should be neglectable.

A memory reference will always be slower than no memory reference
regardless of cache sizes.

Helmut

Bernd Nawothnig

unread,
Aug 12, 2012, 5:04:56 AM8/12/12
to
On 2012-08-12, Helmut Eller wrote:
>> Depends on the CPU and cache size how much that indirection costs. For
>> modern CPUs it should be neglectable.
>
> A memory reference will always be slower than no memory reference
> regardless of cache sizes.

If the whole vector fits into L1 the cache - and that will be the case
if it is relatively small, e.g. 256 entries - accessing the address
will be very fast. No external bus cycles are required. So the
additional costs in such a situation will be neglectable or even zero
in some cases. Precondition for that is, of course, that the vector is
kept in the L1 cache and will stay there. But that will be
automatically the case if the corresponding switch/case is executed
often enough (like in the inner loop of the mentioned Python runtime
interpreter).

Zermelo

unread,
Aug 12, 2012, 5:19:30 AM8/12/12
to
"Pascal J. Bourguignon" <p...@informatimago.com> writes:

> That's ludicruous! In a language where the Duff device is valid,
> there's no reason to prevent jumping into or out of loops.

I know you can jump into a loop. As a matter of fact that is exactly the
situation where you need a brute-force goto, because if you adhere
strictly to the structured programming tenets you will need a lot of
awkward flags.

But the point I was replying to was another: if you can
simulate a jumping-into-a-scope goto using only an array of
pointers. And that is not possible, as far as I know (obviously that
question is little pertinent with lisp programming...)

Nicolas Neuss

unread,
Aug 14, 2012, 4:42:32 AM8/14/12
to
Bernd Nawothnig <Bernd.N...@t-online.de> writes:

> You can be very sure that I would get another answer for the same
> question in the C++ group ;-)

The difference being that many people here in c.l.l. know C++ reasonably
well, whereas in the C++ group almost no one knows anything about Common
Lisp.

Nicolas

tar...@google.com

unread,
Aug 14, 2012, 4:48:15 PM8/14/12
to
Any reason you can't just use CASE?
Or do you need to have the ability to "fall through" cases?

0 new messages