Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This question already has an answer here:

I'm looking for a language that will let me do what I could do with Clipper years ago, and which I can do with Tcl, namely add functionality in a way other than just adding functions.

For example in Clipper/(x)Harbour there are commands #command, #translate, #xcommand and #xtranslate that allow things like this:

#xcommand REPEAT; 
   => DO WHILE .T. 
#xcommand UNTIL <cond>; 
  =>     IF (<cond>); 
             ;EXIT; 
         ;ENDIF; 
     ;ENDDO 

LOCAL n := 1
REPEAT
    n := n + 1
UNTIL n > 100

Similarly, in Tcl I'm doing

proc process_range {_for_ project _from_ dat1 _to_ dat2 _by_ slice} {
    set fromDate [clock scan $dat1]
    set toDate   [clock scan $dat2]

    if {$slice eq "day"} then {set incrementor [expr 24 * 60]}
    if {$slice eq "hour"} then {set incrementor 60}

    set method DateRange

    puts "Scanning from [clock format $fromDate -format "%c"] to [clock format $toDate -format "%c"] by $slice"
    for {set dateCursor $fromDate} {$dateCursor <= $toDate} {set dateCursor [clock add $dateCursor $incrementor minutes]} {
        # ...
    }
}
process_range for "client" from "2013-10-18 00:00" to "2013-10-20 23:59" by day

Are there any other languages that permit this kind of, almost COBOL-esque, syntax modification?

If you're wondering why I'm asking, it's for setting up stuff so that others with a not-as-geeky-as-I-am skillset can declare processing tasks.

share|improve this question

marked as duplicate by MichaelT, gnat, GlenH7, World Engineer Oct 22 '13 at 1:08

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
Looks like you're looking for the power of Lisp macros. Beware... –  Florian Margaine Oct 20 '13 at 14:01
    
Beware indeed! I fear that the staff I'm preparing this for would faint/freak/flail/flee at the sight of Lisp. –  boost Oct 20 '13 at 14:58
    
I wonder if anyone will mention the Logix language. –  boost Oct 20 '13 at 15:13
    
Or Lhogho for that matter. –  boost Oct 20 '13 at 15:15
    
Seeing what you want to do, I suggest you look at BDD frameworks. –  Florian Margaine Oct 20 '13 at 15:44

2 Answers 2

up vote 1 down vote accepted

There are many languages out there that are quite flexible. Many (often newer) languages pride themselves in their suitability for domain-specific languages (DSLs). However, some of your examples need some macro system.

Some languages that prominently use macros:

  • Lisp and descendants. These work as abstract syntax tree (AST) substitutions.
  • C, C++. The C preprocessor uses token-level subtitution, and is less powerful than Lisp macros. Your first example can be directly translated to C macros:

    // untested
    #define repeat for(;;) {
    #define until(cond) if(cond) break; }
    
    auto n = 1;
    repeat {
      n++;
    } until(n > 100)
    

Many languages allow functions to be called with keywords. Examples include

  • Lisps like Common Lisp.
  • Smalltalk and descendants.
  • Python:
  • Some languages have syntax that allow to fake named arguments, e.g.

    • many command-line interfaces:

      git commit --file=foo.txt --message="Some fixes" --author=me
      
    • Any language with dictionary literals
      • Perl.
      • Javascript: foo.bar({ x: 42, y: somethingElse }).

Languages that have function literals/lambdas/closures don't need macros to define new control flow.

  • Any functional language, e.g. Lisps, ML
  • Smalltalk and descendants. Especially noteworthy is Ruby with its ubiquitous do ... end blocks.
  • With clumsy syntax: C++11, Perl, Javascript.

There are some languages that have a flexible view on operators, so that a lot of punctuation like parens for function calls etc. can be left out. An example would be Scala.

share|improve this answer

Lisp macros are probably a good examples of the kind of feature you are looking for. They basically allow you to extend the language in relatively arbitrary ways.

Effectively, a macro is a function that gets executed at compile time, and can produce whatever code you like. Lisps are well suited to this kind of technique because they are homoiconic - which means that code is itself expressed in Lisp data structures. So your macro just needs to produce a data structure that represents the code that you want.

Here's an example from Clojure that adds a C-style for loop to the language:

(defmacro for-loop 
  "Runs an imperative for loop, binding sym to init, running code as long as check is true, 
  updating sym according to change"
  ([[sym init check change :as params] & code]
    `(loop [~sym ~init value# nil]
       (if ~check
         (recur ~change (do ~@code))
         value#))))

(for-loop [i, 0, (< i 10), (inc i)]
  (println i))
=> prints the numbers from 0 to 9 inclusive as you would expect

As you can see - it only takes a few lines of code to add a new language construct.

One caveat: this is a powerful technique and should be used with care. In general, you shouldn't use a macro when a normal function would do the job.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.