Skip to content

Instantly share code, notes, and snippets.

@getzdan
Created December 9, 2015 14:34
Show Gist options
  • Save getzdan/75136f130c6f8ffeb60e to your computer and use it in GitHub Desktop.
Save getzdan/75136f130c6f8ffeb60e to your computer and use it in GitHub Desktop.
A non-breaking Julia control-flow change to separate the One language from mortal languages, doomed to die

A non-breaking Julia control-flow change to separate the One language from mortal languages, doomed to die

From a design patterns and DRY perspective it seems for loops together with the break statement are serving as a useful try/catch mechanism for non-error situations. A common pattern defines a variable before a for loop and tries to discern, using said variable, the circumstances of exiting the for loop. Leveraging the embedded mental construct of try/catch blocks, we can simplify this repeating pattern and make it easier and more readable.

The syntax can look as follows:

for ...(loop vars here)...
   ...(local vars here)...
   ...
   if ...
      break <value>
   end
   ...
catch <symbol>
   ...(access local/loop vars and <symbol> here)...
   <for-value>
finally
   ...(access local/loop vars here)...
   <for-value>
end

Syntax changes worthy of consideration should be self-explanatory to many, as I hope this suggestion is. But an example should help:

After change:

for line in eachline(f)
    fields = split(line)
    status = fileds[2]
    if status=="FAIL"
        break
    end
catch
    println("Test $(fields[1]) failed with reason $(fields[3])")
finally
    println("Test successful!")
end

Before change:

fields = []
didfail = false
for line in eachline(f)
	fields = split(line)
	status = fields[2]
	if status=="FAIL"
		didfail = true
		break
	end
end
if didfail
	println("Test $(fields[1]) failed with reason $(fields[3])")
else
	println("Test successful!")
end

The above example does not use the break <value> suggestion. With multiple break circumstances it should be useful to have separate code for each circumstance. One option is to replicate the try/catch form with a <value> passed as <symbol>, another would be to use catch <value> to run catch block if "break <value> == catch <value>" (the <value> can be a human readable symbol). A direct jump in the LLVM code to the appropriate catch block would be an easy optimization to implement.

Another issue to consider is the return value of a for block. The suggestion above adds the option to change the current default nothing return with <for-value> in the new optional blocks.

Notice that the catch and finally blocks are completely optional and therefore backward compatibility is easy. Additionally there are no additional keywords and block nesting would not conflict with try/catch.

Hey, Julia is still < 0.9 so there is still time for some change.

Obligatory Disclaimerism:

  1. This has already been considered before by name/issue.
  2. Before suggesting I should have studied past discussions more.
  3. Other langauges actually already have this... bla bla.
  4. This post is what it is.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment