[Haskell-cafe] Re: [Off topic] Proving an impossibility

Sterling Clover s.clover at gmail.com
Tue Sep 4 23:47:17 EDT 2007


You get the logic and code blowup problems that require either local  
variables, breaks, gotos, or continuations because you're working  
with tests that generate side-effects. Mixing side-effects and tests  
is going to generate a goto, sure, but if the code was rewritten in a  
functional style the problems would go away, even in an imperative  
context.

Or even:

myFunc E' = if E' do
	S
	if not F then do
		T
		myFunc E

main = do myFunc E

of course you could rewrite this in a while loop too although you'd  
have to use an assignment, but at least still not one with a silly  
"done" variable.

E' = E
while(E')
	S
	if not F
		T
		E' = E
endwhile

I've actually used this sort of construct plenty of times in  
imperative languages (putting "fenceposts" in a list generated by an  
enumerator, etc.)  because its clearer and simpler than break. Break  
isn't as bad as goto, but it can also lead to difficulty reasoning  
about large functions along the same lines. in Java I often find  
myself initializing a return value upfront and then setting it  
according to the logic of the program rather than calling "return" at  
arbitrary points for the same reason again -- it lets you avoid  
duplicate cleanup code and reason clearly about the flow of control  
in your program. Of course, this is what a "finally" block is for,  
except finally blocks are ugly, while unwindProtect in, say, lisp, is  
somewhat neater except it breaks with full continuations, which is  
why, as i understand it with my still limited Haskell-fu, a monadic  
context that you can enter and exit is the cleanest way to enforce  
this stuff, and it works precisely because the pure functionality is  
enforced. Okay, now I'm rambling.

Except that I do note, now, that assignment, and I suppose procedures  
are disallowed as well because the original question was apparently  
only with regards to "using just the if and while statement" (which I  
assume would also disallow the logical operators used in the initial  
post as well). All of which maybe, is just therefore the professor's  
way to push students to realize that if and while *alone* are  
insufficiently expressive to generate all possible flow control  
combinations (i.e. one can't construct an if/while calculus the same  
way one can construct an S K one).

--S


> while E do
>   S
>   if F then
>      break
>   end
>   T
> end

On Sep 4, 2007, at 11:39 AM, Tillmann Rendel wrote:

> Vimal wrote:
>> Ah, yes, it is possible in this case, but you have used an extra  
>> variable.
>> It is okay, but our professor doesnt want to put emphasis on
>> Computability here (or maybe I dont realize it), but the point is:  
>> Are
>> such programming constructs really necessary in a programming
>> language? i.e. Is Breakl, goto, falling through switch/case
>> statements, necessary in a language?
>
> If your (or your professor's) question is not about computabily,  
> but about expressivenes, what's the point of asking for a proof? In  
> a turing-complete language, everything should be expressible :)
>
> Sensible questions may include: how easy is it to express a  
> language feature using only other language features? (local or  
> global transformation needed, code blowup, mechanical  
> transformation or rewrite-from-scratch?)
>
>> This also brings another point. What if there are N loops like this,
>> and there is no break statement available in your language? You would
>> have to use N conditional variables, and would make mainting the code
>> a horrible thing to do.
>
> I disagree. You would have to introduce a temporary variable for  
> every breakable loop, an assignment to the approbiate variable for  
> every break and a lot of tests of temporary variables to skip parts  
> of the loop body. Since breaks can only occur withing the loop  
> body, and each break only breaks the innermost loop, all of these  
> temporary variables can share the same name and shadow each other  
> in the case of nested loops. by reserving a approbiate name (like  
> "done") for this variable by convention.
>
> Reading such code, you can just just resugar the code by reading  
> "if not done then", "done := true" and "let var done = false in  
> while ..." as primitives.
>
> This is a local transformation, the code blowup is linear and it is  
> possible to do it mechanically. I therefore consider the break  
> statement as easily emulated by temporary variables.
>
> On the other hand, the obvious next step would be to provide actual  
> names for these three uses of the "done"-variable, either by using  
> whatever abstraction means provided by the language, or by adding  
> syntactic sugar. In Haskell, we would simply define an approbiate  
> monad to hide the "if not done then"-parts in the bind operation  
> and reuse the existing syntactic sugar for monadic expressions.
>
>   Tillmann
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list