Modulinos: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added AppleScript.)
m (→‎{{header|Wren}}: Minor tidy)
 
(12 intermediate revisions by 7 users not shown)
Line 5:
 
Sometimes getting the [[ScriptName]] is required in order to determine when to run main().
 
Care when manipulating command line arguments, due to subtle exec security constraints that may or not be enforced on implicit argv[0]. https://ryiron.wordpress.com/2013/12/16/argv-silliness/
 
: ''This is still a draft task, and the current task description has caused mega confusion. See '''[[Talk:Modulinos]]''' for numerous attempts to understand the task and to rewrite the task description.''
Line 12 ⟶ 14:
 
=={{header|11l}}==
<langsyntaxhighlight lang="11l">// life.11l
 
F meaning_of_life()
Line 18 ⟶ 20:
 
:start:
print(‘Main: The meaning of life is ’meaning_of_life())</langsyntaxhighlight>
 
<langsyntaxhighlight lang="11l">// death.11l
 
print(‘Life means ’life:meaning_of_life()‘.’)
print(‘Death means nothing.’)</langsyntaxhighlight>
 
=={{header|AppleScript}}==
Line 29 ⟶ 31:
AppleScript's equivalent of a main() function is a <tt>run</tt> handler, which can be either implicit or explicit:
 
<langsyntaxhighlight lang="applescript">display dialog "Hello"</langsyntaxhighlight>
or
<langsyntaxhighlight lang="applescript">on run
display dialog "Hello"
end run</langsyntaxhighlight>
 
A <tt>run</tt> handler's only executed when the script containing it is explicity ''run'', either from another script or application or as an application in its own right. It's not executed when a script's simply loaded as a library, although it can subsequently be so in the unlikely event of this being desirable. Scripts saved as applications aren't recognised by the "Libraries" system introduced in Mac OS X 10.9, but can be loaded and/or run using the older <tt>load script</tt> and <tt>run script</tt> commands. Script code can tell if it's running in its own application or being executed by an external agent by comparing its file path with that of the agent:
 
<langsyntaxhighlight lang="applescript">on run
if ((path to me) = (path to current application)) then
display dialog "I'm running in my own application."
Line 43 ⟶ 45:
display dialog "I'm being run from another script or application."
end if
end run</langsyntaxhighlight>
 
=={{header|Arturo}}==
Line 49 ⟶ 51:
===Library===
 
<langsyntaxhighlight lang="rebol">; modulinos - library
meaningOfLife: function [][
Line 56 ⟶ 58:
 
if standalone? ->
print ~"Library: The meaning of life is |meaningOfLife|"</langsyntaxhighlight>
 
{{out}}
Line 64 ⟶ 66:
===Main===
 
<langsyntaxhighlight lang="rebol">do.import relative "modulinos - library.art"
print ~"Life means |meaningOfLife|."
print "Death means invisible scary skeletons."</langsyntaxhighlight>
 
{{out}}
Line 82 ⟶ 84:
Example
 
<langsyntaxhighlight lang="sh">$ make
./scriptedmain
Main: The meaning of life is 42
./test
Test: The meaning of life is</langsyntaxhighlight>
 
Makefile
 
<langsyntaxhighlight lang="make">all: scriptedmain test
./scriptedmain
./test
Line 104 ⟶ 106:
-rm test
-rm scriptedmain.exe
-rm test.exe</langsyntaxhighlight>
 
scriptedmain.h
 
<syntaxhighlight lang ="c">int meaning_of_life();</langsyntaxhighlight>
 
scriptedmain.c
 
<langsyntaxhighlight lang="c">#include <stdio.h>
 
int meaning_of_life() {
Line 126 ⟶ 128:
}
 
#endif</langsyntaxhighlight>
 
test.c
 
<langsyntaxhighlight lang="c">#include "scriptedmain.h"
#include <stdio.h>
 
Line 138 ⟶ 140:
printf("Test: The meaning of life is %d\n", meaning_of_life());
return 0;
}</langsyntaxhighlight>
 
=={{header|C++}}==
Line 145 ⟶ 147:
Example
 
<langsyntaxhighlight lang="sh">$ make
./scriptedmain
Main: The meaning of life is 42
./test
Test: The meaning of life is 42</langsyntaxhighlight>
 
Makefile
 
<langsyntaxhighlight lang="make">all: scriptedmain test
./scriptedmain
./test
Line 167 ⟶ 169:
-rm test
-rm scriptedmain.exe
-rm test.exe</langsyntaxhighlight>
 
scriptedmain.h
 
<syntaxhighlight lang ="cpp">int meaning_of_life();</langsyntaxhighlight>
 
scriptedmain.cpp
 
<langsyntaxhighlight lang="cpp">#include <iostream>
 
using namespace std;
Line 190 ⟶ 192:
}
 
#endif</langsyntaxhighlight>
 
test.cpp
 
<langsyntaxhighlight lang="cpp">#include "scriptedmain.h"
#include <iostream>
 
Line 204 ⟶ 206:
cout << "Test: The meaning of life is " << meaning_of_life() << endl;
return 0;
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
Line 210 ⟶ 212:
 
scriptedmain.clj:
<langsyntaxhighlight lang="clojure">":";exec lein exec $0 ${1+"$@"}
":";exit
 
Line 222 ⟶ 224:
 
(when (.contains (first *command-line-args*) *source-path*)
(apply -main (rest *command-line-args*)))</langsyntaxhighlight>
 
test.clj:
<langsyntaxhighlight lang="clojure">":";exec lein exec $0 ${1+"$@"}
":";exit
 
Line 237 ⟶ 239:
 
(when (.contains (first *command-line-args*) *source-path*)
(apply -main (rest *command-line-args*)))</langsyntaxhighlight>
 
=={{header|CoffeeScript}}==
scriptedmain.coffee:
<langsyntaxhighlight lang="coffeescript">#!/usr/bin/env coffee
 
meaningOfLife = () -> 42
Line 250 ⟶ 252:
console.log "Main: The meaning of life is " + meaningOfLife()
 
if not module.parent then main()</langsyntaxhighlight>
 
test.coffee:
<langsyntaxhighlight lang="coffeescript">#!/usr/bin/env coffee
 
sm = require "./scriptedmain"
 
console.log "Test: The meaning of life is " + sm.meaningOfLife()</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Line 266 ⟶ 268:
~/.clisprc.lisp
 
<langsyntaxhighlight lang="lisp">;;; Play nice with shebangs
(set-dispatch-macro-character #\# #\!
(lambda (stream character n)
(declare (ignore character n))
(read-line stream nil nil t)
nil))</langsyntaxhighlight>
 
scriptedmain.lisp
 
<langsyntaxhighlight lang="lisp">#!/bin/sh
#|
exec clisp -q -q $0 $0 ${1+"$@"}
Line 305 ⟶ 307:
args
:test #'(lambda (x y) (search x y :test #'equalp)))
(main args)))</langsyntaxhighlight>
 
test.lisp
 
<langsyntaxhighlight lang="lisp">#!/bin/sh
#|
exec clisp -q -q $0 $0 ${1+"$@"}
Line 316 ⟶ 318:
 
(load "scriptedmain.lisp")
(format t "Test: The meaning of life is ~a~%" (meaning-of-life))</langsyntaxhighlight>
 
=={{header|D}}==
Line 324 ⟶ 326:
scriptedmain.d:
 
<langsyntaxhighlight lang="d">#!/usr/bin/env rdmd -version=scriptedmain
 
module scriptedmain;
Line 338 ⟶ 340:
writeln("Main: The meaning of life is ", meaningOfLife());
}
}</langsyntaxhighlight>
 
test.d:
 
<langsyntaxhighlight lang="d">#!/usr/bin/env rdmd -version=test
 
import scriptedmain;
Line 351 ⟶ 353:
writeln("Test: The meaning of life is ", meaningOfLife());
}
}</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight lang="sh">$ ./scriptedmain.d
Main: The meaning of life is 42
$ ./test.d
Line 364 ⟶ 366:
$ dmd test.d scriptedmain.d -version=test
$ ./test
Test: The meaning of life is 42</langsyntaxhighlight>
 
=={{header|Dart}}==
scriptedmain.dart:
<langsyntaxhighlight lang="dart">#!/usr/bin/env dart
 
#library("scriptedmain");
Line 378 ⟶ 380:
main() {
print("Main: The meaning of life is ${meaningOfLife()}");
}</langsyntaxhighlight>
 
test.dart:
<langsyntaxhighlight lang="dart">#!/usr/bin/env dart
 
#import("scriptedmain.dart", prefix: "scriptedmain");
Line 387 ⟶ 389:
main() {
print("Test: The meaning of life is ${scriptedmain.meaningOfLife()}");
}</langsyntaxhighlight>
 
Example:
<langsyntaxhighlight lang="sh">$ ./scriptedmain.dart
Main: The meaning of life is 42
$ ./test.dart
Test: The meaning of life is 42</langsyntaxhighlight>
 
=={{header|Emacs Lisp}}==
Line 400 ⟶ 402:
scriptedmain.el
 
<langsyntaxhighlight lang="lisp">:;exec emacs -batch -l $0 -f main $*
 
;;; Shebang from John Swaby
Line 408 ⟶ 410:
 
(defun main ()
(message "Main: The meaning of life is %d" (meaning-of-life)))</langsyntaxhighlight>
 
test.el
 
<langsyntaxhighlight lang="lisp">:;exec emacs -batch -l $0 -f main $*
 
;;; Shebang from John Swaby
Line 420 ⟶ 422:
(setq load-path (cons default-directory load-path))
(load "scriptedmain.el" nil t)
(message "Test: The meaning of life is %d" (meaning-of-life)))</langsyntaxhighlight>
 
=={{header|EMal}}==
{{trans|Wren}}
<syntaxhighlight lang="emal">
^|We have created a module named ModulinosPart.emal.
|^
in Org:RosettaCode
type ModulinosPart
fun meaningOfLife = int by block do return 42 end
fun main = void by block do writeLine("The meaning of life is " + meaningOfLife() + ".") end
if Runtime.direct() do main() end
</syntaxhighlight>
{{out}}
<pre>
emal.exe Org\RosettaCode\ModulinosPart.emal
The meaning of life is 42.
</pre>
<syntaxhighlight lang="emal">
^|Then we create a new module named Modulinos.emal,
|this imports the previous module.
|^
in Org:RosettaCode
load :ModulinosPart
type Modulinos
fun main = int by List args
writeLine("Who says the meaning of life is " + ModulinosPart.meaningOfLife() + "?")
return 0
end
exit main(Runtime.args)
</syntaxhighlight>
{{out}}
<pre>
emal.exe Org\RosettaCode\Modulinos.emal
Who says the meaning of life is 42?
</pre>
 
=={{header|Erlang}}==
Line 426 ⟶ 463:
 
Makefile:
<langsyntaxhighlight lang="make">all: t
 
t: scriptedmain.beam test.beam
Line 439 ⟶ 476:
 
clean:
-rm *.beam</langsyntaxhighlight>
 
scriptedmain.erl:
<langsyntaxhighlight lang="erlang">-module(scriptedmain).
-export([meaning_of_life/0, start/0]).
 
Line 449 ⟶ 486:
start() ->
io:format("Main: The meaning of life is ~w~n", [meaning_of_life()]),
init:stop().</langsyntaxhighlight>
 
test.erl:
<langsyntaxhighlight lang="erlang">-module(test).
-export([start/0]).
-import(scriptedmain, [meaning_of_life/0]).
Line 458 ⟶ 495:
start() ->
io:format("Test: The meaning of life is ~w~n", [meaning_of_life()]),
init:stop().</langsyntaxhighlight>
 
=={{header|F Sharp|F#}}==
Line 472 ⟶ 509:
Example:
 
<langsyntaxhighlight lang="sh">$ make
fsharpc --out:scriptedmain.exe ScriptedMain.fs
fsharpc --out:test.exe ScriptedMain.fs Test.fs
Line 478 ⟶ 515:
Main: The meaning of life is 42
$ mono test.exe
Test: The meaning of life is 42</langsyntaxhighlight>
 
Makefile:
 
<langsyntaxhighlight lang="make">all: scriptedmain.exe test.exe
 
scriptedmain.exe: ScriptedMain.fs
Line 491 ⟶ 528:
 
clean:
-rm *.exe</langsyntaxhighlight>
 
ScriptedMain.fs:
 
<langsyntaxhighlight lang="fsharp">namespace ScriptedMain
 
module ScriptedMain =
Line 501 ⟶ 538:
 
let main =
printfn "Main: The meaning of life is %d" meaningOfLife</langsyntaxhighlight>
 
Test.fs:
 
<langsyntaxhighlight lang="fsharp">module Test =
open ScriptedMain
 
let main =
printfn "Test: The meaning of life is %d" ScriptedMain.meaningOfLife</langsyntaxhighlight>
 
=={{header|Factor}}==
Line 516 ⟶ 553:
Example:
 
<langsyntaxhighlight lang="sh">$ ./scriptedmain.factor
Main: The meaning of life is 42
$ ./test.factor
Test: The meaning of life is 42</langsyntaxhighlight>
 
~/.factor-rc:
 
<langsyntaxhighlight lang="factor">! INCLUDING macro that imports source code files in the current directory
 
USING: kernel vocabs.loader parser sequences lexer vocabs.parser ;
Line 530 ⟶ 567:
: include-vocab ( vocab -- ) dup ".factor" append parse-file append use-vocab ;
 
SYNTAX: INCLUDING: ";" [ include-vocab ] each-token ;</langsyntaxhighlight>
 
scriptedmain.factor:
 
<langsyntaxhighlight lang="factor">#! /usr/bin/env factor
 
USING: io math.parser ;
Line 543 ⟶ 580:
: main ( -- ) meaning-of-life "Main: The meaning of life is " write number>string print ;
 
MAIN: main</langsyntaxhighlight>
 
test.factor:
 
<langsyntaxhighlight lang="factor">#! /usr/bin/env factor
 
INCLUDING: scriptedmain ;
Line 555 ⟶ 592:
: main ( -- ) meaning-of-life "Test: The meaning of life is " write number>string print ;
 
MAIN: main</langsyntaxhighlight>
 
=={{header|Forth}}==
Line 561 ⟶ 598:
Given this awful running reference:
 
<langsyntaxhighlight lang="forth">42 constant Douglas-Adams
 
: go ( -- )
." The meaning of life is " Douglas-Adams . cr ;</langsyntaxhighlight>
 
The bulk of Forth systems provide a way to generate an executable that enters GO (ar any word) on start.
Line 570 ⟶ 607:
{{works with|SwiftForth|SwiftForth|4.0}}
 
<langsyntaxhighlight lang="forth">' go 'MAIN !
program douglas-adams</langsyntaxhighlight>
 
Which creates a file named 'douglas-adams' that you can then run. If this is all in the same file, you can load the file, test parts of it, and then exit (or shell out) to run the executable.
Line 579 ⟶ 616:
{{works with|gforth}}
 
<langsyntaxhighlight lang="forth">#! /usr/bin/env gforth
 
42 constant Douglas-Adams
.( The meaning of life is ) Douglas-Adams . cr bye</langsyntaxhighlight>
 
Adding #! as a comment, as gforth does, is trivial. For a means by which this script could distinguish between 'scripted execution' and otherwise, a symlink like 'forthscript' could easily be used, and the zeroth OS argument tested for, but there's no convention.
Line 588 ⟶ 625:
{{works with|gforth}}
 
<langsyntaxhighlight lang="forth">#! /usr/bin/env forthscript
 
42 constant Douglas-Adams
Line 596 ⟶ 633:
[THEN]
 
cr .( Why aren't you running this as a script? It only provides a constant.)</langsyntaxhighlight>
 
 
=={{header|FreeBASIC}}==
{{trans|Ring}}
<syntaxhighlight lang="freebasic">
Function meaningoflife() As Byte
Dim As Byte y = 42
Return y
End Function
 
Sub main()
Print "Main: The meaning of life is "; meaningoflife()
End Sub
 
main()
Sleep
</syntaxhighlight>
{{out}}
<pre>
Main: The meaning of life is 42
</pre>
 
 
=={{header|Go}}==
Line 604 ⟶ 663:
 
First create these two files in the 'modulino' directory:
<langsyntaxhighlight lang="go">// modulino.go
package main
 
Line 615 ⟶ 674:
func libMain() {
fmt.Println("The meaning of life is", MeaningOfLife())
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="go">// modulino_main.go
package main
func main() {
libMain()
}</langsyntaxhighlight>
 
To emulate a modulino:
Line 633 ⟶ 692:
 
Now create this file in the 'mol' directory:
<langsyntaxhighlight lang="go">// mol.go
package main
 
Line 640 ⟶ 699:
func main() {
fmt.Println("The meaning of life is still", MeaningOfLife())
}</langsyntaxhighlight>
and copy modulino.go to the 'mol' directory. The library can then be used in the 'normal' way:
{{out}}
Line 653 ⟶ 712:
Example:
 
<langsyntaxhighlight lang="sh">$ ./ScriptedMain.groovy
Main: The meaning of life is 42
$ ./Test.groovy
Test: The meaning of life is 42</langsyntaxhighlight>
 
ScriptedMain.groovy:
 
<langsyntaxhighlight lang="groovy">#!/usr/bin/env groovy
 
class ScriptedMain {
Line 668 ⟶ 727:
println "Main: The meaning of life is " + meaningOfLife
}
}</langsyntaxhighlight>
 
Test.groovy:
 
<langsyntaxhighlight lang="groovy">#!/usr/bin/env groovy
 
println "Test: The meaning of life is " + ScriptedMain.meaningOfLife</langsyntaxhighlight>
 
=={{header|Haskell}}==
Haskell has scripted main, but getting scripted main to work with compiled scripts is tricky.
 
<langsyntaxhighlight lang="sh">$ runhaskell scriptedmain.hs
Main: The meaning of life is 42
$ runhaskell test.hs
Line 688 ⟶ 747:
$ ghc -fforce-recomp -o test -main-is Test test.hs scriptedmain.hs
$ ./test
Test: The meaning of life is 42</langsyntaxhighlight>
 
scriptedmain.hs
 
<langsyntaxhighlight lang="haskell">#!/usr/bin/env runhaskell
 
-- Compile:
Line 704 ⟶ 763:
 
main :: IO ()
main = putStrLn $ "Main: The meaning of life is " ++ show meaningOfLife</langsyntaxhighlight>
 
test.hs
 
<langsyntaxhighlight lang="haskell">#!/usr/bin/env runhaskell
 
-- Compile:
Line 719 ⟶ 778:
 
main :: IO ()
main = putStrLn $ "Test: The meaning of life is " ++ show meaningOfLife</langsyntaxhighlight>
 
=={{header|Io}}==
Line 725 ⟶ 784:
ScriptedMain.io:
 
<langsyntaxhighlight lang="io">#!/usr/bin/env io
 
ScriptedMain := Object clone
Line 732 ⟶ 791:
if( isLaunchScript,
"Main: The meaning of life is #{ScriptedMain meaningOfLife}" interpolate println
)</langsyntaxhighlight>
 
test.io:
 
<langsyntaxhighlight lang="io">#!/usr/bin/env io
 
"Test: The meaning of life is #{ScriptedMain meaningOfLife}" interpolate println</langsyntaxhighlight>
 
<langsyntaxhighlight lang="sh">$ ./ScriptedMain.io
Main: The meaning of life is 42
$ ./test.io
Test: The meaning of life is 42</langsyntaxhighlight>
 
=={{header|J}}==
Line 749 ⟶ 808:
modulinos.ijs:
 
<langsyntaxhighlight lang="j">#!/usr/bin/env ijconsole
meaningOfLife =: 42
Line 764 ⟶ 823:
)
shouldrun 0</langsyntaxhighlight>
 
test.j:
 
<langsyntaxhighlight lang="j">#!/usr/bin/env jconsole
 
load 'modulinos.ijs'
Line 774 ⟶ 833:
echo 'Test: The meaning of life is ',": meaningOfLife
 
exit ''</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight lang="sh">$ ./modulinos.ijs
Main: The meaning of life is 42
$ ./test.j
Test: The meaning of life is 42</langsyntaxhighlight>
 
=={{header|Java}}==
Line 788 ⟶ 847:
ScriptedMain.java
 
<langsyntaxhighlight lang="java">public class ScriptedMain {
public static int meaningOfLife() {
return 42;
Line 796 ⟶ 855:
System.out.println("Main: The meaning of life is " + meaningOfLife());
}
}</langsyntaxhighlight>
 
Test.java
 
<langsyntaxhighlight lang="java">public class Test {
public static void main(String[] args) {
System.out.println("Test: The meaning of life is " + ScriptedMain.meaningOfLife());
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
Line 811 ⟶ 870:
 
scriptedmain.js
<langsyntaxhighlight lang="javascript">#!/usr/bin/env node
 
function meaningOfLife() { return 42; }
Line 821 ⟶ 880:
}
 
if (!module.parent) { main(); }</langsyntaxhighlight>
 
test.js
<langsyntaxhighlight lang="javascript">#!/usr/bin/env node
 
var sm = require("./scriptedmain");
 
console.log("Test: The meaning of life is " + sm.meaningOfLife());</langsyntaxhighlight>
 
=={{header|Julia}}==
Line 834 ⟶ 893:
<br />
In module file Divisors.jl:
<langsyntaxhighlight lang="julia">module Divisors
 
using Primes
Line 875 ⟶ 934:
Divisors.interactiveDivisors()
end
</syntaxhighlight>
</lang>
In a user file getdivisors.jl:
<langsyntaxhighlight lang="julia">include("divisors.jl")
 
using .Divisors
Line 883 ⟶ 942:
n = 708245926330
println("The proper divisors of $n are ", properdivisors(n))
</syntaxhighlight>
</lang>
 
=={{header|LLVM}}==
LLVM can have scripted main a la C, using the weak attribute.
 
<langsyntaxhighlight lang="sh">$ make
llvm-as scriptedmain.ll
llc scriptedmain.bc
Line 898 ⟶ 957:
gcc -o test test.s scriptedmain.s
./test
Test: The meaning of life is 42</langsyntaxhighlight>
 
Makefile
 
<langsyntaxhighlight lang="make">EXECUTABLE_SM=scriptedmain
EXECUTABLE_TEST=test
 
Line 923 ⟶ 982:
-rm test.bc
-rm scriptedmain.s
-rm scriptedmain.bc</langsyntaxhighlight>
 
scriptedmain.ll
 
<langsyntaxhighlight lang="llvm">@msg_main = internal constant [33 x i8] c"Main: The meaning of life is %d\0A\00"
 
declare i32 @printf(i8* noalias nocapture, ...)
Line 941 ⟶ 1,000:
 
ret i32 0
}</langsyntaxhighlight>
 
test.ll
 
<langsyntaxhighlight lang="llvm">@msg_test = internal constant [33 x i8] c"Test: The meaning of life is %d\0A\00"
 
declare i32 @printf(i8* noalias nocapture, ...)
Line 957 ⟶ 1,016:
 
ret i32 0
}</langsyntaxhighlight>
 
=={{header|Lua}}==
Line 964 ⟶ 1,023:
scriptedmain.lua
 
<langsyntaxhighlight lang="lua">#!/usr/bin/env lua
 
function meaningoflife()
Line 978 ⟶ 1,037:
else
module(..., package.seeall)
end</langsyntaxhighlight>
 
test.lua
 
<langsyntaxhighlight lang="lua">#!/usr/bin/env lua
sm = require("scriptedmain")
print("Test: The meaning of life is " .. sm.meaningoflife())</langsyntaxhighlight>
 
=={{header|Make}}==
 
Example
<langsyntaxhighlight lang="sh">$ make -f scriptedmain.mf
The meaning of life is 42
(Main)
$ make -f test.mf
The meaning of life is 42
(Test)</langsyntaxhighlight>
 
scriptedmain.mf
<langsyntaxhighlight lang="make">all: scriptedmain
 
meaning-of-life:
Line 1,004 ⟶ 1,063:
scriptedmain: meaning-of-life
@echo "(Main)"
</syntaxhighlight>
</lang>
 
test.mf
<langsyntaxhighlight lang="make">all: test
 
test:
@make -f scriptedmain.mf meaning-of-life
@echo "(Test)"
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
 
scriptedmain.ma
<langsyntaxhighlight lang="mathematica">#!/usr/bin/env MathKernel -script
 
MeaningOfLife[] = 42
Line 1,032 ⟶ 1,091:
If[StringMatchQ[Program, ".*scriptedmain.*"],
Print["Main: The meaning of life is " <> ToString[MeaningOfLife[]]]
]</langsyntaxhighlight>
 
test.ma:
<langsyntaxhighlight lang="mathematica">#!/usr/bin/env MathKernel -script
 
Get["scriptedmain.ma"]
 
Print["Test: The meaning of life is " <> ToString[MeaningOfLife[]]]</langsyntaxhighlight>
 
Example:
<langsyntaxhighlight lang="sh">$ ./scriptedmain.ma
Main: The meaning of life is 42
$ ./test.ma
Test: The meaning of life is 42</langsyntaxhighlight>
 
In Mac and Windows, the output will be surrounded by spurious quotes.
Line 1,051 ⟶ 1,110:
=={{header|Mozart/Oz}}==
Makefile:
<langsyntaxhighlight lang="make">all: run
 
run: scriptedmain test
Line 1,071 ⟶ 1,130:
-rm *.ozf
-rm *.exe
</syntaxhighlight>
</lang>
 
scriptedmain.oz:
<langsyntaxhighlight lang="oz">functor
export
meaningOfLife: MeaningOfLife
Line 1,092 ⟶ 1,151:
end
end
</syntaxhighlight>
</lang>
 
test.oz:
<langsyntaxhighlight lang="oz">functor
import
ScriptedMain
Line 1,109 ⟶ 1,168:
end
end
end</langsyntaxhighlight>
 
=={{header|newLISP}}==
Line 1,116 ⟶ 1,175:
scriptedmain.lsp
 
<langsyntaxhighlight lang="lisp">#!/usr/bin/env newlisp
 
(context 'SM)
Line 1,128 ⟶ 1,187:
(if (find "scriptedmain" (main-args 1)) (main))
 
(context MAIN)</langsyntaxhighlight>
 
test.lsp
 
<langsyntaxhighlight lang="lisp">#!/usr/bin/env newlisp
 
(load "scriptedmain.lsp")
(println (format "Test: The meaning of life is %d" (SM:meaning-of-life)))
(exit)</langsyntaxhighlight>
 
=={{header|Nim}}==
Nim provides the predicate <code>isMainModule</code> to use with conditional compilation. Here is an example:
 
<syntaxhighlight lang="Nim">proc p*() =
## Some exported procedure.
echo "Executing procedure"
 
# Some code to execute to initialize the module.
echo "Initializing the module"
 
when isMainModule:
# Some code to execute if the module is run directly, for instance code to test the module.
echo "Running tests"
</syntaxhighlight>
 
{{out}}
When run directly, the result of execution is:
<pre>Initializing the module
Running tests
</pre>
If we call “p” from another module, we get:
<pre>Initializing the module
Executing procedure
</pre>
 
=={{header|Objective-C}}==
Line 1,142 ⟶ 1,226:
scriptedmain.h:
 
<langsyntaxhighlight lang="objc">#import <objc/Object.h>
 
@interface ScriptedMain: Object {}
Line 1,148 ⟶ 1,232:
+ (int)meaningOfLife;
 
@end</langsyntaxhighlight>
 
scriptedmain.m:
 
<langsyntaxhighlight lang="objc">#import "scriptedmain.h"
#import <Foundation/Foundation.h>
 
Line 1,171 ⟶ 1,255:
 
return 0;
}</langsyntaxhighlight>
 
test.m:
 
<langsyntaxhighlight lang="objc">#import "scriptedmain.h"
#import <Foundation/Foundation.h>
 
Line 1,186 ⟶ 1,270:
 
return 0;
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="sh">$ gcc -o scriptedmain -lobjc -framework foundation scriptedmain.m
$ gcc -o test -lobjc -framework foundation test.m scriptedmain.m
$ ./scriptedmain
Main: The meaning of life is 42
$ ./test
Test: The meaning of life is 42</langsyntaxhighlight>
 
=={{header|OCaml}}==
Line 1,199 ⟶ 1,283:
scriptedmain.ml
 
<langsyntaxhighlight lang="ocaml">let meaning_of_life = 42
 
let main () =
Line 1,207 ⟶ 1,291:
let () =
if not !Sys.interactive then
main ()</langsyntaxhighlight>
 
Invoked as a script:
 
<langsyntaxhighlight lang="sh">$ ocaml scriptedmain.ml
Main: The meaning of life is 42</langsyntaxhighlight>
 
Loaded into an ocaml toplevel/utop:
 
<syntaxhighlight lang="text">$ ocaml
...
# #use "scriptedmain.ml";;
Line 1,223 ⟶ 1,307:
# meaning_of_life;;
- : int = 42
# </langsyntaxhighlight>
 
The limit of this technique is "avoiding running something when loading a script interactively". It's not applicable to other uses, like adding an example script to a file normally used as a library, as that code will also fire when users of the library are run.
Line 1,232 ⟶ 1,316:
meaningoflife.m
 
<langsyntaxhighlight lang="matlab">#!/usr/bin/env octave -qf
 
function y = meaningoflife()
Line 1,242 ⟶ 1,326:
endfunction
 
main();</langsyntaxhighlight>
 
test.m
 
<langsyntaxhighlight lang="matlab">#!/usr/bin/env octave -qf
 
printf("Test: The meaning of life is %d", meaningoflife());</langsyntaxhighlight>
 
=={{header|Pascal}}==
Line 1,254 ⟶ 1,338:
Makefile:
 
<langsyntaxhighlight lang="make">all: scriptedmain
 
scriptedmain: scriptedmain.pas
Line 1,266 ⟶ 1,350:
-rm scriptedmain
-rm *.o
-rm *.ppu</langsyntaxhighlight>
 
scriptedmain.pas:
 
<langsyntaxhighlight lang="pascal">{$IFDEF scriptedmain}
program ScriptedMain;
{$ELSE}
Line 1,287 ⟶ 1,371:
writeln(MeaningOfLife())
{$ENDIF}
end.</langsyntaxhighlight>
 
test.pas:
 
<langsyntaxhighlight lang="pascal">program Test;
uses
ScriptedMain;
Line 1,297 ⟶ 1,381:
write('Test: The meaning of life is: ');
writeln(MeaningOfLife())
end.</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight lang="sh">$ make
$ ./scriptedmain
Main: The meaning of life is: 42
$ make test
$ ./test
Test: The meaning of life is: 42</langsyntaxhighlight>
 
=={{header|Perl}}==
Perl has scripted main. The code inside <tt>unless(caller) { ... }</tt> only runs when <tt>Life.pm</tt> is the main program.
 
<langsyntaxhighlight lang="perl">#!/usr/bin/env perl
 
# Life.pm
Line 1,325 ⟶ 1,409:
unless(caller) {
print "Main: The meaning of life is " . meaning_of_life() . "\n";
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="perl">#!/usr/bin/env perl
 
# death.pl
Line 1,336 ⟶ 1,420:
 
print "Life means " . Life::meaning_of_life . ".\n";
print "Death means invisible scary skeletons.\n";</langsyntaxhighlight>
 
=={{header|Phix}}==
There is a builtin for this, which can even be asked to skip an arbitrary number of stack frames and that way find out exactly where it was effectively called from.
<!--<syntaxhighlight lang="phix">(notonline)-->
<lang Phix>string mori = iff(include_file()=1?"main":"an include")</lang>
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (includefile)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">mori</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">include_file</span><span style="color: #0000FF;">()=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"main"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"an include"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
 
=={{header|PHP}}==
Line 1,347 ⟶ 1,434:
scriptedmain.php
 
<langsyntaxhighlight lang="php"><?php
function meaning_of_life() {
return 42;
Line 1,359 ⟶ 1,446:
main($argv);
}
?></langsyntaxhighlight>
 
test.php
 
<langsyntaxhighlight lang="php"><?php
require_once("scriptedmain.php");
echo "Test: The meaning of life is " . meaning_of_life() . "\n";
?></langsyntaxhighlight>
 
=={{header|PicoLisp}}==
PicoLisp normally does it the other way round: It calls main from the command line with the '-' syntax if desired. Create an executable file (chmod +x) "life.l":
<langsyntaxhighlight PicoLisplang="picolisp">#!/usr/bin/picolisp /usr/lib/picolisp/lib.l
 
(de meaningOfLife ()
Line 1,377 ⟶ 1,464:
(de lifemain ()
(prinl "Main: The meaning of life is " (meaningOfLife))
(bye) )</langsyntaxhighlight>
and an executable file (chmod +x) "test.l":
<langsyntaxhighlight PicoLisplang="picolisp">#!/usr/bin/picolisp /usr/lib/picolisp/lib.l
 
(load "life.l")
 
(prinl "Test: The meaning of life is " (meaningOfLife))
(bye)</langsyntaxhighlight>
Test:
<pre>$ ./life.l -lifemain
Line 1,395 ⟶ 1,482:
Python has scripted main.
 
<langsyntaxhighlight lang="python">#!/usr/bin/env python
 
# life.py
Line 1,403 ⟶ 1,490:
 
if __name__ == "__main__":
print("Main: The meaning of life is %s" % meaning_of_life())</langsyntaxhighlight>
 
<langsyntaxhighlight lang="python">#!/usr/bin/env python
 
# death.py
Line 1,412 ⟶ 1,499:
 
print("Life means %s." % meaning_of_life())
print("Death means invisible scary skeletons.")</langsyntaxhighlight>
 
=={{header|R}}==
A way to check if code is running at "top level" is to check <code>length(sys.frames())</code>. This value will be zero for a file being run with <code>Rscript</code>, the <code>--file=</code> argument, or at the command line, and will be greater than 0 in all other conditions (such as package loading or code being sourced from another file.)
 
<langsyntaxhighlight Rlang="r">#!/usr/bin/env Rscript
 
meaningOfLife <- function() {
Line 1,431 ⟶ 1,518:
main(args)
q("no")
}</langsyntaxhighlight>
 
test.R
 
<langsyntaxhighlight Rlang="r">#!/usr/bin/env Rscript
 
source("scriptedmain.R")
Line 1,441 ⟶ 1,528:
cat("Test: The meaning of life is", meaningOfLife(), "\n")
 
q("no")</langsyntaxhighlight>
 
=={{header|Racket}}==
scriptedmain.rkt:
<langsyntaxhighlight lang="racket">#!/usr/bin/env racket
#lang racket
 
Line 1,452 ⟶ 1,539:
(define (meaning-of-life) 42)
 
(module+ main (printf "Main: The meaning of life is ~a\n" (meaning-of-life)))</langsyntaxhighlight>
 
test.rkt:
<langsyntaxhighlight lang="racket">#!/usr/bin/env racket
#lang racket
 
(module+ main
(require "scriptedmain.rkt")
(printf "Test: The meaning of life is ~a\n" (meaning-of-life)))</langsyntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
Raku automatically calls MAIN on direct invocation, but this may be a multi dispatch, so a library may have multiple "scripted mains".
<syntaxhighlight lang="raku" perl6line>class LUE {
has $.answer = 42;
}
Line 1,475 ⟶ 1,562:
multi MAIN ('methods') {
say ~LUE.^methods;
}</langsyntaxhighlight>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program detects whether or not it is a "scripted main" program. */
parse source . howInvoked @fn /*query REXX how this pgm got invoked. */
 
Line 1,495 ⟶ 1,582:
/*────────────────────────────── The main code follows here ... ────────────────────────*/
say
say '(from' @fn"): and away we go ···"</langsyntaxhighlight> <br><br>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Modulinos
 
Line 1,507 ⟶ 1,594:
func main()
see "Main: The meaning of life is " + meaningoflife() + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 1,516 ⟶ 1,603:
Ruby has scripted main.
 
<langsyntaxhighlight lang="ruby"># life.rb
 
def meaning_of_life
Line 1,524 ⟶ 1,611:
if __FILE__ == $0
puts "Main: The meaning of life is #{meaning_of_life}"
end</langsyntaxhighlight>
 
<langsyntaxhighlight lang="ruby"># death.rb
 
require 'life'
 
puts "Life means #{meaning_of_life}."
puts "Death means invisible scary skeletons."</langsyntaxhighlight>
 
=={{header|Rust}}==
Line 1,537 ⟶ 1,624:
 
Makefile:
<langsyntaxhighlight lang="make">all: scriptedmain
 
scriptedmain: scriptedmain.rs
Line 1,550 ⟶ 1,637:
-rm -rf *.dylib
-rm scriptedmain
-rm -rf *.dSYM</langsyntaxhighlight>
 
scriptedmain.rs:
<langsyntaxhighlight lang="rust">#[link(name = "scriptedmain")];
 
use std;
Line 1,563 ⟶ 1,650:
fn main() {
std::io::println("Main: The meaning of life is " + core::int::to_str(meaning_of_life(), 10u));
}</langsyntaxhighlight>
 
test.rs:
<langsyntaxhighlight lang="rust">use scriptedmain;
use std;
 
fn main() {
std::io::println("Test: The meaning of life is " + core::int::to_str(scriptedmain::meaning_of_life(), 10u));
}</langsyntaxhighlight>
 
Example:
<langsyntaxhighlight lang="sh">$ make
$ make test
$ ./scriptedmain
Main: The meaning of life is 42
$ ./test
Test: The meaning of life is 42</langsyntaxhighlight>
 
=={{header|SAC}}==
Makefile:
<langsyntaxhighlight lang="make">all: scriptedmain
 
scriptedmain: ScriptedMain.sac
Line 1,599 ⟶ 1,686:
-rm libScriptedMainMod.a
-rm scriptedmain
-rm scriptedmain.c</langsyntaxhighlight>
 
ScriptedMain.sac:
<langsyntaxhighlight lang="c">#ifndef scriptedmain
module ScriptedMain;
#endif
Line 1,619 ⟶ 1,706:
return(0);
}
#endif</langsyntaxhighlight>
 
test.sac:
<langsyntaxhighlight lang="c">use StdIO: all;
use Array: all;
use ScriptedMain: all;
Line 1,629 ⟶ 1,716:
printf("Test: The meaning of life is %d\n", meaning_of_life());
return(0);
}</langsyntaxhighlight>
 
Example:
<langsyntaxhighlight lang="sh">$ make
$ make test
$ ./scriptedmain
Main: The meaning of life is 42
$ ./test
Test: The meaning of life is 42</langsyntaxhighlight>
 
=={{header|Scala}}==
Line 1,645 ⟶ 1,732:
===Unix shell script===
This code must be stored as a shell script.
<langsyntaxhighlight lang="bash">#!/bin/sh
exec scala "$0" "$@"
!#
Line 1,655 ⟶ 1,742:
println(s"Use the routine to show that the hailstone sequence for the number: $nr.")
println(collatz.toList)
println(s"It has ${collatz.length} elements.")</langsyntaxhighlight>
 
===Windows Command Script===
This code must be stored as a Windows Command Script e.g. Hailstone.cmd
<langsyntaxhighlight lang="winbatch">::#!
@echo off
call scala %0 %*
Line 1,673 ⟶ 1,760:
println(collatz.toList)
println(s"It has ${collatz.length} elements.")
</syntaxhighlight>
</lang>
{{out}}
<pre>C:\>Hailstone.cmd 42
Line 1,686 ⟶ 1,773:
scriptedmain.scm
 
<langsyntaxhighlight lang="scheme">#!/bin/sh
#|
exec csi -ss $0 ${1+"$@"}
Line 1,710 ⟶ 1,797:
 
(if (equal? (car (program)) 'compiled)
(main (cdr (argv))))</langsyntaxhighlight>
 
test.scm
 
<langsyntaxhighlight lang="scheme">#!/bin/sh
#|
exec csi -ss $0 ${1+"$@"}
Line 1,722 ⟶ 1,809:
(load "scriptedmain.scm")
(display (format "Test: The meaning of life is ~a\n" (meaning-of-life)))
(exit))</langsyntaxhighlight>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby"># Life.sm
 
func meaning_of_life {
Line 1,733 ⟶ 1,820:
if (__FILE__ == __MAIN__) {
say "Main: The meaning of life is #{meaning_of_life()}"
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="ruby"># test.sf
 
include Life
 
say "Test: The meaning of life is #{Life::meaning_of_life()}."</langsyntaxhighlight>
 
=={{header|Smalltalk}}==
Line 1,747 ⟶ 1,834:
Example
 
<langsyntaxhighlight lang="shell">$ gst-package -t ~/.st package.xml &>/dev/null
 
$ ./scriptedmain.st
Line 1,753 ⟶ 1,840:
 
$ ./test.st
Test: The meaning of life is 42</langsyntaxhighlight>
 
package.xml
 
<langsyntaxhighlight lang="xml"><packages>
<package>
<name>ScriptedMain</name>
Line 1,763 ⟶ 1,850:
<file>scriptedmain.st</file>
</package>
</packages></langsyntaxhighlight>
 
scriptedmain.st
 
<langsyntaxhighlight lang="smalltalk">"exec" "gst" "-f" "$0" "$0" "$@"
"exit"
 
Line 1,782 ⟶ 1,869:
(((Smalltalk getArgc) > 0) and: [ ((Smalltalk getArgv: 1) endsWith: 'scriptedmain.st') ]) ifTrue: [
main value.
].</langsyntaxhighlight>
 
test.st
 
<langsyntaxhighlight lang="smalltalk">"exec" "gst" "-f" "$0" "$0" "$@"
"exit"
 
Line 1,792 ⟶ 1,879:
PackageLoader fileInPackage: 'ScriptedMain'.
 
Transcript show: 'Test: The meaning of life is ', ((ScriptedMain meaningOfLife) printString); cr.</langsyntaxhighlight>
 
=={{header|Swift}}==
Line 1,800 ⟶ 1,887:
Example
 
<langsyntaxhighlight lang="shell">$ make
mkdir -p bin/
swiftc -D SCRIPTEDMAIN -o bin/ScriptedMain ScriptedMain.swift
Line 1,809 ⟶ 1,896:
Main: The meaning of life is 42
bin/Test
Test: The meaning of life is 42</langsyntaxhighlight>
 
Makefile
 
<langsyntaxhighlight lang="make">all: bin/ScriptedMain bin/Test
bin/ScriptedMain
bin/Test
Line 1,833 ⟶ 1,920:
-rm *.swiftdoc
-rm *.dylib
</syntaxhighlight>
</lang>
 
ScriptedMain.swift
 
<langsyntaxhighlight lang="swift">import Foundation
 
public class ScriptedMain {
Line 1,858 ⟶ 1,945:
}
#endif
</syntaxhighlight>
</lang>
 
Test.swift
 
<langsyntaxhighlight lang="swift">import Foundation
import ScriptedMain
 
Line 1,880 ⟶ 1,967:
}
#endif
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc main {args} {
puts "Directory: [pwd]"
puts "Program: $::argv0"
Line 1,892 ⟶ 1,979:
if {$::argv0 eq [info script]} {
main {*}$::argv
}</langsyntaxhighlight>
 
=={{header|UNIX Shell}}==
Line 1,899 ⟶ 1,986:
scriptedmain.sh
 
<langsyntaxhighlight lang="sh">#!/usr/bin/env sh
 
meaning_of_life() {
Line 1,913 ⟶ 2,000:
then
main
fi</langsyntaxhighlight>
 
test.sh
 
<langsyntaxhighlight lang="sh">#!/bin/bash
 
path=$(dirname -- "$0")
Line 1,924 ⟶ 2,011:
meaning_of_life
echo "Test: The meaning of life is $?"
</syntaxhighlight>
</lang>
 
=={{header|Wren}}==
Line 1,932 ⟶ 2,019:
 
First we create a module for our modulino:
<langsyntaxhighlight ecmascriptlang="wren">/* modulinoModulinos.wren */
 
var MeaningOfLife = Fn.new { 42 }
Line 1,942 ⟶ 2,029:
// Check if it's being used as a library or not.
import "os" for Process
if (Process.allArguments[1] == "modulinoModulinos.wren") { // if true, not a library
main.call()
}</langsyntaxhighlight>
 
and run it to make sure it works OK when run directly:
Line 1,953 ⟶ 2,040:
 
Next we create another module which imports the modulino:
<langsyntaxhighlight ecmascriptlang="wren">/* modulino_mainModulinos_main.wren */
 
import "./modulinoModulinos" for MeaningOfLife
 
var main = Fn.new {
Line 1,961 ⟶ 2,048:
}
 
main.call()</langsyntaxhighlight>
 
and run this to make sure the modulino's ''main()'' function doesn't run:
Line 1,973 ⟶ 2,060:
On the ZX Spectrum, there is no main function as such, however a saved program can be made to start running from a particular line number by providing the line number as a parameter to save command. If the program is being merged as a module, then it does not run automatically. The following example will save the program in memory so that it starts running from line 500:
 
<langsyntaxhighlight lang="zxbasic">SAVE "MYPROG" LINE 500: REM For a program with main code starting at line 500</langsyntaxhighlight>
 
{{omit from|Ada}}

Latest revision as of 10:33, 4 January 2024

Modulinos is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

It is useful to be able to execute a main() function only when a program is run directly. This is a central feature in programming scripts. A script that behaves this way is called a modulino.

Examples from https://github.com/mcandre/modulinos

Sometimes getting the ScriptName is required in order to determine when to run main().

Care when manipulating command line arguments, due to subtle exec security constraints that may or not be enforced on implicit argv[0]. https://ryiron.wordpress.com/2013/12/16/argv-silliness/

This is still a draft task, and the current task description has caused mega confusion. See Talk:Modulinos for numerous attempts to understand the task and to rewrite the task description.
The task Executable library is written to replace this task. This task's future is in doubt as its aims are not clear enough.



11l

// life.11l

F meaning_of_life()
   R ‘*’.code

:start:
print(‘Main: The meaning of life is ’meaning_of_life())
// death.11l

print(‘Life means ’life:meaning_of_life()‘.’)
print(‘Death means nothing.’)

AppleScript

AppleScript's equivalent of a main() function is a run handler, which can be either implicit or explicit:

display dialog "Hello"

or

on run
    display dialog "Hello"
end run

A run handler's only executed when the script containing it is explicity run, either from another script or application or as an application in its own right. It's not executed when a script's simply loaded as a library, although it can subsequently be so in the unlikely event of this being desirable. Scripts saved as applications aren't recognised by the "Libraries" system introduced in Mac OS X 10.9, but can be loaded and/or run using the older load script and run script commands. Script code can tell if it's running in its own application or being executed by an external agent by comparing its file path with that of the agent:

on run
    if ((path to me) = (path to current application)) then
        display dialog "I'm running in my own application."
    else
        display dialog "I'm being run from another script or application."
    end if
end run

Arturo

Library

; modulinos - library
 
meaningOfLife: function [][
    42
]

if standalone? ->
    print ~"Library: The meaning of life is |meaningOfLife|"
Output:
Library: The meaning of life is 42

Main

do.import relative "modulinos - library.art"
 
print ~"Life means |meaningOfLife|."
print "Death means invisible scary skeletons."
Output:
Life means 42.
Death means invisible scary skeletons.

C

Works with: GCC

C programs cannot normally do scripted main, because main() is implicitly included by another program, test.c, even though scriptedmain.h omits any main() prototype. However, preprocessor instructions can hide main unless a compiler flag is explicitly set.

Example

$ make
./scriptedmain
Main: The meaning of life is 42
./test
Test: The meaning of life is

Makefile

all: scriptedmain test
	./scriptedmain
	./test

scriptedmain: scriptedmain.c scriptedmain.h
	gcc -o scriptedmain -DSCRIPTEDMAIN scriptedmain.c scriptedmain.h

test: test.c scriptedmain.h scriptedmain.c
	gcc -o test test.c scriptedmain.c scriptedmain.h

clean:
	-rm scriptedmain
	-rm test
	-rm scriptedmain.exe
	-rm test.exe

scriptedmain.h

int meaning_of_life();

scriptedmain.c

#include <stdio.h>

int meaning_of_life() {
	return 42;
}

#ifdef SCRIPTEDMAIN

int main() {
	printf("Main: The meaning of life is %d\n", meaning_of_life());

	return 0;
}

#endif

test.c

#include "scriptedmain.h"
#include <stdio.h>

extern int meaning_of_life();

int main(int argc, char **argv) {
	printf("Test: The meaning of life is %d\n", meaning_of_life());
	return 0;
}

C++

C++ programs cannot normally do scripted main, because main() is implicitly included by another program, test.c, even though scriptedmain.h omits any main() prototype. Preprocessor instructions can hide main() unless a compiler flat is explicitly set.

Example

$ make
./scriptedmain
Main: The meaning of life is 42
./test
Test: The meaning of life is 42

Makefile

all: scriptedmain test
	./scriptedmain
	./test

scriptedmain: scriptedmain.cpp scriptedmain.h
	g++ -o scriptedmain -static-libgcc -static-libstdc++ -DSCRIPTEDMAIN scriptedmain.cpp scriptedmain.h

test: test.cpp scriptedmain.h scriptedmain.cpp
	g++ -o test -static-libgcc -static-libstdc++ test.cpp scriptedmain.cpp scriptedmain.h

clean:
	-rm scriptedmain
	-rm test
	-rm scriptedmain.exe
	-rm test.exe

scriptedmain.h

int meaning_of_life();

scriptedmain.cpp

#include <iostream>

using namespace std;

int meaning_of_life() {
	return 42;
}

#ifdef SCRIPTEDMAIN

int main() {
	cout << "Main: The meaning of life is " << meaning_of_life() << endl;
	return 0;
}

#endif

test.cpp

#include "scriptedmain.h"
#include <iostream>

using namespace std;

extern int meaning_of_life();

int main() {
	cout << "Test: The meaning of life is " << meaning_of_life() << endl;
	return 0;
}

Clojure

Uses lein-exec.

scriptedmain.clj:

":";exec lein exec $0 ${1+"$@"}
":";exit

(ns scriptedmain
  (:gen-class))

(defn meaning-of-life [] 42)

(defn -main [& args]
  (println "Main: The meaning of life is" (meaning-of-life)))

(when (.contains (first *command-line-args*) *source-path*)
  (apply -main (rest *command-line-args*)))

test.clj:

":";exec lein exec $0 ${1+"$@"}
":";exit

(ns test
  (:gen-class))

(load-string (slurp "scriptedmain.clj"))

(defn -main [& args]
  (println "Test: The meaning of life is" (scriptedmain/meaning-of-life)))

(when (.contains (first *command-line-args*) *source-path*)
  (apply -main (rest *command-line-args*)))

CoffeeScript

scriptedmain.coffee:

#!/usr/bin/env coffee

meaningOfLife = () -> 42

exports.meaningOfLife = meaningOfLife

main = () ->
  console.log "Main: The meaning of life is " + meaningOfLife()

if not module.parent then main()

test.coffee:

#!/usr/bin/env coffee

sm = require "./scriptedmain"

console.log "Test: The meaning of life is " + sm.meaningOfLife()

Common Lisp

Common Lisp has few standards for POSIX operation. Shebangs and command line arguments are hacks.

In CLISP, this code only works for ./scriptedmain.lisp.

~/.clisprc.lisp

;;; Play nice with shebangs
(set-dispatch-macro-character #\# #\!
 (lambda (stream character n)
  (declare (ignore character n))
  (read-line stream nil nil t)
  nil))

scriptedmain.lisp

#!/bin/sh
#|
exec clisp -q -q $0 $0 ${1+"$@"}
exit
|#

;;; Usage: ./scriptedmain.lisp

(defun meaning-of-life () 42)

(defun main (args)
 (format t "Main: The meaning of life is ~a~%" (meaning-of-life))
 (quit))

;;; With help from Francois-Rene Rideau
;;; http://tinyurl.com/cli-args
(let ((args
       #+clisp ext:*args*
       #+sbcl sb-ext:*posix-argv*
       #+clozure (ccl::command-line-arguments)
       #+gcl si:*command-args*
       #+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
       #+cmu extensions:*command-line-strings*
       #+allegro (sys:command-line-arguments)
       #+lispworks sys:*line-arguments-list*
     ))

  (if (member (pathname-name *load-truename*)
              args
              :test #'(lambda (x y) (search x y :test #'equalp)))
    (main args)))

test.lisp

#!/bin/sh
#|
exec clisp -q -q $0 $0 ${1+"$@"}
exit
|#

(load "scriptedmain.lisp")
(format t "Test: The meaning of life is ~a~%" (meaning-of-life))

D

D manages to implement scriptedmain through the use of version directives, which require special options to rdmd and dmd.

scriptedmain.d:

#!/usr/bin/env rdmd -version=scriptedmain

module scriptedmain;

import std.stdio;

int meaningOfLife() {
	return 42;
}

version (scriptedmain) {
	void main(string[] args) {
		writeln("Main: The meaning of life is ", meaningOfLife());
	}
}

test.d:

#!/usr/bin/env rdmd -version=test

import scriptedmain;
import std.stdio;

version (test) {
	void main(string[] args) {
		writeln("Test: The meaning of life is ", meaningOfLife());
	}
}

Example:

$ ./scriptedmain.d
Main: The meaning of life is 42
$ ./test.d
Test: The meaning of life is 42
$ dmd scriptedmain.d -version=scriptedmain
$ ./scriptedmain
Main: The meaning of life is 42
$ dmd test.d scriptedmain.d -version=test
$ ./test
Test: The meaning of life is 42

Dart

scriptedmain.dart:

#!/usr/bin/env dart

#library("scriptedmain");

meaningOfLife() {
	return 42;
}

main() {
	print("Main: The meaning of life is ${meaningOfLife()}");
}

test.dart:

#!/usr/bin/env dart

#import("scriptedmain.dart", prefix: "scriptedmain");

main() {
	print("Test: The meaning of life is ${scriptedmain.meaningOfLife()}");
}

Example:

$ ./scriptedmain.dart 
Main: The meaning of life is 42
$ ./test.dart 
Test: The meaning of life is 42

Emacs Lisp

Emacs has scripted main, though older versions require an obscure shebang syntax.

scriptedmain.el

:;exec emacs -batch -l $0 -f main $*

;;; Shebang from John Swaby
;;; http://www.emacswiki.org/emacs/EmacsScripts

(defun meaning-of-life () 42)

(defun main ()
 (message "Main: The meaning of life is %d" (meaning-of-life)))

test.el

:;exec emacs -batch -l $0 -f main $*

;;; Shebang from John Swaby
;;; http://www.emacswiki.org/emacs/EmacsScripts

(defun main ()
 (setq load-path (cons default-directory load-path))
 (load "scriptedmain.el" nil t)
 (message "Test: The meaning of life is %d" (meaning-of-life)))

EMal

Translation of: Wren
^|We have created a module named ModulinosPart.emal.
 |^
in Org:RosettaCode
type ModulinosPart
fun meaningOfLife = int by block do return 42 end
fun main = void by block do writeLine("The meaning of life is " + meaningOfLife() + ".") end
if Runtime.direct() do main() end
Output:
emal.exe Org\RosettaCode\ModulinosPart.emal
The meaning of life is 42.
^|Then we create a new module named Modulinos.emal,
 |this imports the previous module.
 |^
in Org:RosettaCode
load :ModulinosPart
type Modulinos
fun main = int by List args
  writeLine("Who says the meaning of life is " + ModulinosPart.meaningOfLife() + "?")
  return 0
end
exit main(Runtime.args)
Output:
emal.exe Org\RosettaCode\Modulinos.emal
Who says the meaning of life is 42?

Erlang

Erlang has scripted main by default. scriptedmain.erl must be compiled before test.erl can access its functions.

Makefile:

all: t

t: scriptedmain.beam test.beam
	erl -noshell -s scriptedmain
	erl -noshell -s test

scriptedmain.beam: scriptedmain.erl
	erlc scriptedmain.erl

test.beam: test.erl
	erlc test.erl

clean:
	-rm *.beam

scriptedmain.erl:

-module(scriptedmain).
-export([meaning_of_life/0, start/0]).

meaning_of_life() -> 42.

start() ->
  io:format("Main: The meaning of life is ~w~n", [meaning_of_life()]),
  init:stop().

test.erl:

-module(test).
-export([start/0]).
-import(scriptedmain, [meaning_of_life/0]).

start() ->
  io:format("Test: The meaning of life is ~w~n", [meaning_of_life()]),
  init:stop().

F#

Note 1: F# supports the scriptedmain behavior, but F# does not support hybrid script-compiled code files. The following programs work provided that they are compiled and then run, as .fs files, not interpreted or dotslashed as .fsx files.

Note 2: fsharpc has a backwards file ordering: Specify any dependencies BEFORE the code that depends on them.

Note 3: fsharpc also has that unpredictable DOS-flavored command line flag syntax, so the --out requires a colon between it and its value, and -h only generates an error; use --help instead.

Note 4: In Unix, mono is required to run F# executables. In Windows, mono is not required for execution.

Example:

$ make
fsharpc --out:scriptedmain.exe ScriptedMain.fs
fsharpc --out:test.exe ScriptedMain.fs Test.fs
$ mono scriptedmain.exe 
Main: The meaning of life is 42
$ mono test.exe 
Test: The meaning of life is 42

Makefile:

all: scriptedmain.exe test.exe

scriptedmain.exe: ScriptedMain.fs
	fsharpc --nologo --out:scriptedmain.exe ScriptedMain.fs

test.exe: Test.fs ScriptedMain.fs
	fsharpc --nologo --out:test.exe ScriptedMain.fs Test.fs

clean:
	-rm *.exe

ScriptedMain.fs:

namespace ScriptedMain

module ScriptedMain =
    let meaningOfLife = 42

    let main =
        printfn "Main: The meaning of life is %d" meaningOfLife

Test.fs:

module Test =
    open ScriptedMain

    let main =
        printfn "Test: The meaning of life is %d" ScriptedMain.meaningOfLife

Factor

Note: The INCLUDE/INCLUDING macros must be added to the ~/.factor-rc configuration file.

Example:

$ ./scriptedmain.factor 
Main: The meaning of life is 42
$ ./test.factor 
Test: The meaning of life is 42

~/.factor-rc:

! INCLUDING macro that imports source code files in the current directory

USING: kernel vocabs.loader parser sequences lexer vocabs.parser ;
IN: syntax

: include-vocab ( vocab -- ) dup ".factor" append parse-file append use-vocab ;

SYNTAX: INCLUDING: ";" [ include-vocab ] each-token ;

scriptedmain.factor:

#! /usr/bin/env factor

USING: io math.parser ;
IN: scriptedmain

: meaning-of-life ( -- n ) 42 ;

: main ( -- ) meaning-of-life "Main: The meaning of life is " write number>string print ;

MAIN: main

test.factor:

#! /usr/bin/env factor

INCLUDING: scriptedmain ;
USING: io math.parser ;
IN: test

: main ( -- ) meaning-of-life "Test: The meaning of life is " write number>string print ;

MAIN: main

Forth

Given this awful running reference:

42 constant Douglas-Adams

: go ( -- )
  ." The meaning of life is " Douglas-Adams . cr ;

The bulk of Forth systems provide a way to generate an executable that enters GO (ar any word) on start.

Works with: SwiftForth version 4.0
' go 'MAIN !
program douglas-adams

Which creates a file named 'douglas-adams' that you can then run. If this is all in the same file, you can load the file, test parts of it, and then exit (or shell out) to run the executable.

A unix script requires that '#!' be a comment and that the system have some #!-compatible arguments.

Works with: gforth
#! /usr/bin/env gforth

42 constant Douglas-Adams
.( The meaning of life is ) Douglas-Adams . cr bye

Adding #! as a comment, as gforth does, is trivial. For a means by which this script could distinguish between 'scripted execution' and otherwise, a symlink like 'forthscript' could easily be used, and the zeroth OS argument tested for, but there's no convention.

Works with: gforth
#! /usr/bin/env forthscript

42 constant Douglas-Adams

s" forthscript" 0 arg compare 0= [IF]
  .( The meaning of life is ) Douglas-Adams . cr bye
[THEN]

cr .( Why aren't you running this as a script?  It only provides a constant.)


FreeBASIC

Translation of: Ring
Function meaningoflife() As Byte
    Dim As Byte y = 42
    Return y
End Function

Sub main()
    Print "Main: The meaning of life is "; meaningoflife()
End Sub

main()
Sleep
Output:
Main: The meaning of life is 42


Go

Go doesn't support scripted main directly.

Although the examples linked to above include an example for Go, this is only a work around, not an emulation. To emulate a modulino, we need to proceed as in the [Executable library] task and split the 'main' package into two.

First create these two files in the 'modulino' directory:

// modulino.go
package main

import "fmt"

func MeaningOfLife() int {
    return 42
}

func libMain() {
    fmt.Println("The meaning of life is", MeaningOfLife())
}
// modulino_main.go
package main
 
func main() {
    libMain()
}

To emulate a modulino:

Output:
$ go run modulino

The meaning of life is 42

Now create this file in the 'mol' directory:

// mol.go
package main

import "fmt"

func main() {
    fmt.Println("The meaning of life is still", MeaningOfLife())
}

and copy modulino.go to the 'mol' directory. The library can then be used in the 'normal' way:

Output:
$ go run mol

The meaning of life is still 42

Groovy

Example:

$ ./ScriptedMain.groovy 
Main: The meaning of life is 42
$ ./Test.groovy 
Test: The meaning of life is 42

ScriptedMain.groovy:

#!/usr/bin/env groovy

class ScriptedMain {
	static def meaningOfLife = 42

	static main(args) {
		println "Main: The meaning of life is " + meaningOfLife
	}
}

Test.groovy:

#!/usr/bin/env groovy

println "Test: The meaning of life is " + ScriptedMain.meaningOfLife

Haskell

Haskell has scripted main, but getting scripted main to work with compiled scripts is tricky.

$ runhaskell scriptedmain.hs
Main: The meaning of life is 42
$ runhaskell test.hs
Test: The meaning of life is 42
$ ghc -fforce-recomp -o scriptedmain -main-is ScriptedMain scriptedmain.hs
$ ./scriptedmain
Main: The meaning of life is 42
$ ghc -fforce-recomp -o test -main-is Test test.hs scriptedmain.hs
$ ./test
Test: The meaning of life is 42

scriptedmain.hs

#!/usr/bin/env runhaskell

-- Compile:
--
-- ghc -fforce-recomp -o scriptedmain -main-is ScriptedMain scriptedmain.hs

module ScriptedMain where

meaningOfLife :: Int
meaningOfLife = 42

main :: IO ()
main = putStrLn $ "Main: The meaning of life is " ++ show meaningOfLife

test.hs

#!/usr/bin/env runhaskell

-- Compile:
--
-- ghc -fforce-recomp -o test -main-is Test test.hs scriptedmain.hs

module Test where

import ScriptedMain hiding (main)

main :: IO ()
main = putStrLn $ "Test: The meaning of life is " ++ show meaningOfLife

Io

ScriptedMain.io:

#!/usr/bin/env io

ScriptedMain := Object clone
ScriptedMain meaningOfLife := 42

if( isLaunchScript,
    "Main: The meaning of life is #{ScriptedMain meaningOfLife}" interpolate println
)

test.io:

#!/usr/bin/env io

"Test: The meaning of life is #{ScriptedMain meaningOfLife}" interpolate println
$ ./ScriptedMain.io 
Main: The meaning of life is 42
$ ./test.io
Test: The meaning of life is 42

J

modulinos.ijs:

#!/usr/bin/env ijconsole
 
meaningOfLife =: 42
 
main =: monad define
	echo 'Main: The meaning of life is ',": meaningOfLife
	exit ''
)

shouldrun =: monad define
	if. 1 e. 'modulinos.ijs' E. ;ARGV do.
		main 0
	end.
)
 
shouldrun 0

test.j:

#!/usr/bin/env jconsole

load 'modulinos.ijs'

echo 'Test: The meaning of life is ',": meaningOfLife

exit ''

Example:

$ ./modulinos.ijs
Main: The meaning of life is 42
$ ./test.j
Test: The meaning of life is 42

Java

Java has scripted main by default.

ScriptedMain.java

public class ScriptedMain {
	public static int meaningOfLife() {
		return 42;
	}

	public static void main(String[] args) {
		System.out.println("Main: The meaning of life is " + meaningOfLife());
	}
}

Test.java

public class Test {
	public static void main(String[] args) {
		System.out.println("Test: The meaning of life is " + ScriptedMain.meaningOfLife());
	}
}

JavaScript

Works with: Node.js

Node.js has scripted main.

scriptedmain.js

#!/usr/bin/env node

function meaningOfLife() { return 42; }

exports.meaningOfLife = meaningOfLife;

function main() {
	console.log("Main: The meaning of life is " + meaningOfLife());
}

if (!module.parent) { main(); }

test.js

#!/usr/bin/env node

var sm = require("./scriptedmain");

console.log("Test: The meaning of life is " + sm.meaningOfLife());

Julia

Julia does not use scripted main by default, but can be set to run as such. Modules generally use a /test unit test subdirectory instead.
In module file Divisors.jl:

module Divisors

using Primes

export properdivisors

function properdivisors(n::T) where T <: Integer
    0 < n || throw(ArgumentError("number to be factored must be ≥ 0, got $n"))
    1 < n || return T[]
    !isprime(n) || return T[one(T), n]
    f = factor(n)
    d = T[one(T)]
    for (k, v) in f
        c = T[k^i for i in 0:v]
        d = d*c'
        d = reshape(d, length(d))
    end
    sort!(d)
    return d[1:end-1]
end

function interactiveDivisors()
    println("\nFind proper divisors between two numbers.\nFirst number: ")
    lo = (x = tryparse(Int64, readline())) == nothing ? 0 : x
    println("\nSecond number: ")
    hi = (x = tryparse(Int64, readline())) == nothing ? 10 : x
    lo, hi = lo > hi ? (hi, lo) : (lo, hi)

    println("Listing the proper divisors for $lo through $hi.")
    for i in lo:hi
        println(lpad(i, 7), "  =>  ", rpad(properdivisors(i), 10))
    end
end

end

# some testing code
if occursin(r"divisors.jl"i, Base.PROGRAM_FILE)
    println("This module is running as main.\n")
    Divisors.interactiveDivisors()
end

In a user file getdivisors.jl:

include("divisors.jl")

using .Divisors

n = 708245926330
println("The proper divisors of $n are ", properdivisors(n))

LLVM

LLVM can have scripted main a la C, using the weak attribute.

$ make
llvm-as scriptedmain.ll
llc scriptedmain.bc
gcc -o scriptedmain scriptedmain.s
./scriptedmain
Main: The meaning of life is 42
llvm-as test.ll
llc test.bc
gcc -o test test.s scriptedmain.s
./test
Test: The meaning of life is 42

Makefile

EXECUTABLE_SM=scriptedmain
EXECUTABLE_TEST=test

all: test.ll scriptedmain.s
	llvm-as test.ll
	llc test.bc
	gcc -o $(EXECUTABLE_TEST) test.s scriptedmain.s
	./$(EXECUTABLE_TEST)

scriptedmain.s: scriptedmain.ll
	llvm-as scriptedmain.ll
	llc scriptedmain.bc
	gcc -o $(EXECUTABLE_SM) scriptedmain.s
	./$(EXECUTABLE_SM)

clean:
	-rm $(EXECUTABLE_TEST)
	-rm $(EXECUTABLE_SM)
	-rm test.s
	-rm test.bc
	-rm scriptedmain.s
	-rm scriptedmain.bc

scriptedmain.ll

@msg_main = internal constant [33 x i8] c"Main: The meaning of life is %d\0A\00"

declare i32 @printf(i8* noalias nocapture, ...)

define i32 @meaning_of_life() {
	ret i32 42
}

define weak i32 @main(i32 %argc, i8** %argv) {
	%meaning = call i32 @meaning_of_life()

	call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([33 x i8]* @msg_main, i32 0, i32 0), i32 %meaning)

	ret i32 0
}

test.ll

@msg_test = internal constant [33 x i8] c"Test: The meaning of life is %d\0A\00"

declare i32 @printf(i8* noalias nocapture, ...)

declare i32 @meaning_of_life()

define i32 @main(i32 %argc, i8** %argv) {
	%meaning = call i32 @meaning_of_life()

	call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([33 x i8]* @msg_test, i32 0, i32 0), i32 %meaning)

	ret i32 0
}

Lua

Lua has scripted main by default because files are largely indistinguishable from functions semantically (they compile to Lua functions.) Ellipses is Lua's var-arg syntax for functions, and, therefore, for files as well.

scriptedmain.lua

#!/usr/bin/env lua

function meaningoflife()
	return 42
end

function main(arg)
	print("Main: The meaning of life is " .. meaningoflife())
end

if type(package.loaded[(...)]) ~= "userdata" then
	main(arg)
else
	module(..., package.seeall)
end

test.lua

#!/usr/bin/env lua
sm = require("scriptedmain")
print("Test: The meaning of life is " .. sm.meaningoflife())

Make

Example

$ make -f scriptedmain.mf 
The meaning of life is 42
(Main)
$ make -f test.mf 
The meaning of life is 42
(Test)

scriptedmain.mf

all: scriptedmain

meaning-of-life:
	@echo "The meaning of life is 42"

scriptedmain: meaning-of-life
	@echo "(Main)"

test.mf

all: test

test:
	@make -f scriptedmain.mf meaning-of-life
	@echo "(Test)"

Mathematica/Wolfram Language

scriptedmain.ma

#!/usr/bin/env MathKernel -script

MeaningOfLife[] = 42

ScriptName[] = Piecewise[
	{
		{"Interpreted", Position[$CommandLine, "-script", 1] == {}}
	},
	$CommandLine[[Position[$CommandLine, "-script", 1][[1,1]] + 1]]
]

Program = ScriptName[];

If[StringMatchQ[Program, ".*scriptedmain.*"],
	Print["Main: The meaning of life is " <> ToString[MeaningOfLife[]]]
]

test.ma:

#!/usr/bin/env MathKernel -script

Get["scriptedmain.ma"]

Print["Test: The meaning of life is " <> ToString[MeaningOfLife[]]]

Example:

$ ./scriptedmain.ma
Main: The meaning of life is 42
$ ./test.ma
Test: The meaning of life is 42

In Mac and Windows, the output will be surrounded by spurious quotes.

Mozart/Oz

Makefile:

all: run

run: scriptedmain test
	./scriptedmain
	./test

scriptedmain: scriptedmain.oz
	ozc -x scriptedmain.oz

scriptedmain.ozf: scriptedmain.oz
	ozc -c scriptedmain.oz

test: scriptedmain.ozf test.oz
	ozc -x test.oz

clean:
	-rm test
	-rm scriptedmain
	-rm *.ozf
	-rm *.exe

scriptedmain.oz:

functor
export
  meaningOfLife: MeaningOfLife
import
  System
  Application
  Property
  Regex at 'x-oz://contrib/regex'
define
  fun {MeaningOfLife} 42 end

  local ScriptName = {Property.get 'application.url'} in
    if {Regex.search "scriptedmain" ScriptName} \= false then
      {System.printInfo "Main: The meaning of life is "#{Int.toString {MeaningOfLife}}#"\n"}
      {Application.exit 0}
    end
  end
end

test.oz:

functor
import
  ScriptedMain
  System
  Application
  Property
  Regex at 'x-oz://contrib/regex'
define
  local ScriptName = {Property.get 'application.url'} in
    if {Regex.search "test" ScriptName} \= false then
      {System.printInfo "Test: The meaning of life is "#{Int.toString {ScriptedMain.meaningOfLife}}#"\n"}
      {Application.exit 0}
    end
  end
end

newLISP

newLISP lacks scripted main, but the feature is easily added.

scriptedmain.lsp

#!/usr/bin/env newlisp

(context 'SM)

(define (SM:meaning-of-life) 42)

(define (main)
	(println (format "Main: The meaning of life is %d" (meaning-of-life)))
	(exit))

(if (find "scriptedmain" (main-args 1)) (main))

(context MAIN)

test.lsp

#!/usr/bin/env newlisp

(load "scriptedmain.lsp")
(println (format "Test: The meaning of life is %d" (SM:meaning-of-life)))
(exit)

Nim

Nim provides the predicate isMainModule to use with conditional compilation. Here is an example:

proc p*() =
  ## Some exported procedure.
  echo "Executing procedure"

# Some code to execute to initialize the module.
echo "Initializing the module"

when isMainModule:
  # Some code to execute if the module is run directly, for instance code to test the module.
  echo "Running tests"
Output:

When run directly, the result of execution is:

Initializing the module
Running tests

If we call “p” from another module, we get:

Initializing the module
Executing procedure

Objective-C

scriptedmain.h:

#import <objc/Object.h>

@interface ScriptedMain: Object {}

+ (int)meaningOfLife;

@end

scriptedmain.m:

#import "scriptedmain.h"
#import <Foundation/Foundation.h>

@implementation ScriptedMain

+ (int)meaningOfLife {
	return 42;
}

@end

int __attribute__((weak)) main(int argc, char **argv) {
	@autoreleasepool {

		printf("Main: The meaning of life is %d\n", [ScriptedMain meaningOfLife]);

	}

	return 0;
}

test.m:

#import "scriptedmain.h"
#import <Foundation/Foundation.h>

int main(int argc, char **argv) {
	@autoreleasepool {

		printf("Test: The meaning of life is %d\n", [ScriptedMain meaningOfLife]);

	}

	return 0;
}
$ gcc -o scriptedmain -lobjc -framework foundation scriptedmain.m
$ gcc -o test -lobjc -framework foundation test.m scriptedmain.m
$ ./scriptedmain 
Main: The meaning of life is 42
$ ./test 
Test: The meaning of life is 42

OCaml

scriptedmain.ml

let meaning_of_life = 42

let main () =
  Printf.printf "Main: The meaning of life is %d\n"
    meaning_of_life

let () =
  if not !Sys.interactive then
    main ()

Invoked as a script:

$ ocaml scriptedmain.ml
Main: The meaning of life is 42

Loaded into an ocaml toplevel/utop:

$ ocaml
...
# #use "scriptedmain.ml";;
val meaning_of_life : int = 42
val main : unit -> unit = <fun>
# meaning_of_life;;
- : int = 42
#

The limit of this technique is "avoiding running something when loading a script interactively". It's not applicable to other uses, like adding an example script to a file normally used as a library, as that code will also fire when users of the library are run.

Octave/MATLAB

Octave and MATLAB have scripted main by default, because only the first function listed in a program are importable by other programs.

meaningoflife.m

#!/usr/bin/env octave -qf

function y = meaningoflife()
	y = 42;
endfunction

function main()
	printf("Main: The meaning of life is %d", meaningoflife());
endfunction

main();

test.m

#!/usr/bin/env octave -qf

printf("Test: The meaning of life is %d", meaningoflife());

Pascal

Works with: Free_Pascal

Makefile:

all: scriptedmain

scriptedmain: scriptedmain.pas
	fpc -dscriptedmain scriptedmain.pas

test: test.pas scriptedmain
	fpc test.pas

clean:
	-rm test
	-rm scriptedmain
	-rm *.o
	-rm *.ppu

scriptedmain.pas:

{$IFDEF scriptedmain}
program ScriptedMain;
{$ELSE}
unit ScriptedMain;
interface
function MeaningOfLife () : integer;
implementation
{$ENDIF}
	function MeaningOfLife () : integer;
	begin
		MeaningOfLife := 42
	end;
{$IFDEF scriptedmain}
begin
	write('Main: The meaning of life is: ');
	writeln(MeaningOfLife())
{$ENDIF}
end.

test.pas:

program Test;
uses
	ScriptedMain;
begin
	write('Test: The meaning of life is: ');
	writeln(MeaningOfLife())
end.

Example:

$ make
$ ./scriptedmain 
Main: The meaning of life is: 42
$ make test
$ ./test 
Test: The meaning of life is: 42

Perl

Perl has scripted main. The code inside unless(caller) { ... } only runs when Life.pm is the main program.

#!/usr/bin/env perl

# Life.pm
package Life;

use strict;
use warnings;

sub meaning_of_life {
	return 42;
}

unless(caller) {
	print "Main: The meaning of life is " . meaning_of_life() . "\n";
}
#!/usr/bin/env perl

# death.pl
use strict;
use warnings;

use Life;

print "Life means " . Life::meaning_of_life . ".\n";
print "Death means invisible scary skeletons.\n";

Phix

There is a builtin for this, which can even be asked to skip an arbitrary number of stack frames and that way find out exactly where it was effectively called from.

without js -- (includefile)
string mori = iff(include_file()=1?"main":"an include")

PHP

PHP does not have scripted main, but the feature is easily added with a regular expression.

scriptedmain.php

<?php
function meaning_of_life() {
	return 42;
}

function main($args) {
	echo "Main: The meaning of life is " . meaning_of_life() . "\n";
}

if (preg_match("/scriptedmain/", $_SERVER["SCRIPT_NAME"])) {
	main($argv);
}
?>

test.php

<?php
require_once("scriptedmain.php");
echo "Test: The meaning of life is " . meaning_of_life() . "\n";
?>

PicoLisp

PicoLisp normally does it the other way round: It calls main from the command line with the '-' syntax if desired. Create an executable file (chmod +x) "life.l":

#!/usr/bin/picolisp /usr/lib/picolisp/lib.l

(de meaningOfLife ()
   42 )

(de lifemain ()
   (prinl "Main: The meaning of life is " (meaningOfLife))
   (bye) )

and an executable file (chmod +x) "test.l":

#!/usr/bin/picolisp /usr/lib/picolisp/lib.l

(load "life.l")

(prinl "Test: The meaning of life is " (meaningOfLife))
(bye)

Test:

$ ./life.l -lifemain
Main: The meaning of life is 42

$ ./test.l
Test: The meaning of life is 42

Python

Python has scripted main.

#!/usr/bin/env python

# life.py

def meaning_of_life():
  return 42

if __name__ == "__main__":
  print("Main: The meaning of life is %s" % meaning_of_life())
#!/usr/bin/env python

# death.py

from life import meaning_of_life

print("Life means %s." % meaning_of_life())
print("Death means invisible scary skeletons.")

R

A way to check if code is running at "top level" is to check length(sys.frames()). This value will be zero for a file being run with Rscript, the --file= argument, or at the command line, and will be greater than 0 in all other conditions (such as package loading or code being sourced from another file.)

#!/usr/bin/env Rscript

meaningOfLife <- function() {
	42
}

main <- function(args) {
	cat("Main: The meaning of life is", meaningOfLife(), "\n")
}

if (length(sys.frames()) > 0) {
        args <- commandArgs(trailingOnly = FALSE)
	main(args)
	q("no")
}

test.R

#!/usr/bin/env Rscript

source("scriptedmain.R")

cat("Test: The meaning of life is", meaningOfLife(), "\n")

q("no")

Racket

scriptedmain.rkt:

#!/usr/bin/env racket
#lang racket

(provide meaning-of-life)

(define (meaning-of-life) 42)

(module+ main (printf "Main: The meaning of life is ~a\n" (meaning-of-life)))

test.rkt:

#!/usr/bin/env racket
#lang racket

(module+ main
	(require "scriptedmain.rkt")
	(printf "Test: The meaning of life is ~a\n" (meaning-of-life)))

Raku

(formerly Perl 6) Raku automatically calls MAIN on direct invocation, but this may be a multi dispatch, so a library may have multiple "scripted mains".

class LUE {
    has $.answer = 42;
}

multi MAIN ('test') {
    say "ok" if LUE.new.answer == 42;
}

multi MAIN ('methods') {
    say ~LUE.^methods;
}

REXX

/*REXX program detects  whether or not  it is a  "scripted main"  program.              */
parse source . howInvoked @fn                    /*query REXX how this pgm got invoked. */

say 'This program  ('@fn")  was invoked as a: "    howInvoked

if howInvoked\=='COMMAND'  then do
                                say 'This program  ('@fn")  wasn't invoked via a command."
                                exit 12
                                end

    /*╔════════════════════════════════════════════════════════════════════════════════╗
      ║  At this point, we know that this program was invoked via the  "command line"  ║
      ║  or a program using the  "command interface"  and  not  via another program.   ║
      ╚════════════════════════════════════════════════════════════════════════════════╝*/

/*────────────────────────────── The main code follows here ... ────────────────────────*/
say
say '(from' @fn"):  and away we go ···"



Ring

# Project : Modulinos

func meaningoflife()	
       y = 42
       return y
 
func main()
       see "Main: The meaning of life is " + meaningoflife() + nl

Output:

Main: The meaning of life is 42

Ruby

Ruby has scripted main.

# life.rb

def meaning_of_life
  42
end

if __FILE__ == $0
  puts "Main: The meaning of life is #{meaning_of_life}"
end
# death.rb

require 'life'

puts "Life means #{meaning_of_life}."
puts "Death means invisible scary skeletons."

Rust

Note: this code is deprecated, and does not compile with Rust 1.0.0 and newer.

Makefile:

all: scriptedmain

scriptedmain: scriptedmain.rs
	rustc scriptedmain.rs

test: test.rs scriptedmain.rs
	rustc --lib scriptedmain.rs
	rustc test.rs -L .

clean:
	-rm test
	-rm -rf *.dylib
	-rm scriptedmain
	-rm -rf *.dSYM

scriptedmain.rs:

#[link(name = "scriptedmain")];

use std;

fn meaning_of_life() -> int {
	ret 42;
}

fn main() {
	std::io::println("Main: The meaning of life is " + core::int::to_str(meaning_of_life(), 10u));
}

test.rs:

use scriptedmain;
use std;

fn main() {
	std::io::println("Test: The meaning of life is " + core::int::to_str(scriptedmain::meaning_of_life(), 10u));
}

Example:

$ make
$ make test
$ ./scriptedmain
Main: The meaning of life is 42
$ ./test
Test: The meaning of life is 42

SAC

Makefile:

all: scriptedmain

scriptedmain: ScriptedMain.sac
	sac2c -o scriptedmain ScriptedMain.sac -Dscriptedmain

test: test.sac ScriptedMain.sac
	sac2c ScriptedMain.sac
	sac2c -o test test.sac

clean:
	-rm test
	-rm test.c
	-rm libScriptedMainTree.so
	-rm libScriptedMainMod.so
	-rm libScriptedMainMod.a
	-rm scriptedmain
	-rm scriptedmain.c

ScriptedMain.sac:

#ifndef scriptedmain
module ScriptedMain;
#endif

use StdIO: all;
use Array: all;
export all;

int meaning_of_life() {
	return(42);
}

#ifdef scriptedmain
int main() {
	printf("Main: The meaning of life is %d\n", meaning_of_life());
	return(0);
}
#endif

test.sac:

use StdIO: all;
use Array: all;
use ScriptedMain: all;

int main() {
	printf("Test: The meaning of life is %d\n", meaning_of_life());
	return(0);
}

Example:

$ make
$ make test
$ ./scriptedmain 
Main: The meaning of life is 42
$ ./test 
Test: The meaning of life is 42

Scala

Library: Scala
Works with: Scala version 2.10.2

Unix shell script

This code must be stored as a shell script.

#!/bin/sh
exec scala "$0" "$@"
!#
  def hailstone(n: Int): Stream[Int] =
       n #:: (if (n == 1) Stream.empty else hailstone(if (n % 2 == 0) n / 2 else n * 3 + 1))

  val nr = argv.headOption.map(_.toInt).getOrElse(27)
  val collatz = hailstone(nr)
  println(s"Use the routine to show that the hailstone sequence for the number: $nr.")
  println(collatz.toList)
  println(s"It has ${collatz.length} elements.")

Windows Command Script

This code must be stored as a Windows Command Script e.g. Hailstone.cmd

::#!
@echo off
call scala %0 %*
pause
goto :eof
::!#
  def hailstone(n: Int): Stream[Int] =
       n #:: (if (n == 1) Stream.empty else hailstone(if (n % 2 == 0) n / 2 else n * 3 + 1))

  val nr = argv.headOption.map(_.toInt).getOrElse(27)
  val collatz = hailstone(nr)
  println(s"Use the routine to show that the hailstone sequence for the number: $nr.")
  println(collatz.toList)
  println(s"It has ${collatz.length} elements.")
Output:
C:\>Hailstone.cmd 42
Use the routine to show that the hailstone sequence for the number: 42.
List(42, 21, 64, 32, 16, 8, 4, 2, 1)
It has 9 elements.

Scheme

Works with: Chicken Scheme

Chicken Scheme has the {{{ -ss }}} flag for the interpreter, but compiled Chicken Scheme programs do not have scripted main unless the behavior is added manually to the code.

scriptedmain.scm

#!/bin/sh
#|
exec csi -ss $0 ${1+"$@"}
exit
|#

(use posix)
(require-extension srfi-1) ; lists

(define (meaning-of-life) 42)

(define (main args)
	(display (format "Main: The meaning of life is ~a\n" (meaning-of-life)))
	(exit))

(define (program)
	(if (string=? (car (argv)) "csi")
		(let ((s-index (list-index (lambda (x) (string-contains x "-s")) (argv))))
			(if (number? s-index)
				(cons 'interpreted (list-ref (argv) (+ 1 s-index)))
				(cons 'unknown "")))
		(cons 'compiled (car (argv)))))

(if (equal? (car (program)) 'compiled)
	(main (cdr (argv))))

test.scm

#!/bin/sh
#|
exec csi -ss $0 ${1+"$@"}
exit
|#
(define (main args)
	(load "scriptedmain.scm")
	(display (format "Test: The meaning of life is ~a\n" (meaning-of-life)))
	(exit))

Sidef

# Life.sm

func meaning_of_life {
    42
}

if (__FILE__ == __MAIN__) {
    say "Main: The meaning of life is #{meaning_of_life()}"
}
# test.sf

include Life

say "Test: The meaning of life is #{Life::meaning_of_life()}."

Smalltalk

Note that the ScriptedMain package must be installed in order for test.st to access code from scriptedmain.st.

Example

$ gst-package -t ~/.st package.xml &>/dev/null

$ ./scriptedmain.st
Main: The meaning of life is 42

$ ./test.st
Test: The meaning of life is 42

package.xml

<packages>
<package>
	<name>ScriptedMain</name>
	<filein>scriptedmain.st</filein>
	<file>scriptedmain.st</file>
</package>
</packages>

scriptedmain.st

"exec" "gst" "-f" "$0" "$0" "$@"
"exit"

Object subclass: ScriptedMain [
	ScriptedMain class >> meaningOfLife [ ^42 ]
]

| main |

main := [
	Transcript show: 'Main: The meaning of life is ', ((ScriptedMain meaningOfLife) printString); cr.
].

(((Smalltalk getArgc) > 0) and: [ ((Smalltalk getArgv: 1) endsWith: 'scriptedmain.st') ]) ifTrue: [
	main value.
].

test.st

"exec" "gst" "-f" "$0" "$0" "$@"
"exit"

"
PackageLoader fileInPackage: 'ScriptedMain'.

Transcript show: 'Test: The meaning of life is ', ((ScriptedMain meaningOfLife) printString); cr.

Swift

Swift requires a number of hacks and boilerplate, but it is possible to write a modulino nevertheless.

Example

$ make
mkdir -p bin/
swiftc -D SCRIPTEDMAIN -o bin/ScriptedMain ScriptedMain.swift
swiftc -emit-library -module-name ScriptedMain -emit-module ScriptedMain.swift
mkdir -p bin/
swiftc -D TEST -o bin/Test Test.swift -I "." -L "." -lScriptedMain -module-link-name ScriptedMain
bin/ScriptedMain
Main: The meaning of life is 42
bin/Test
Test: The meaning of life is 42

Makefile

all: bin/ScriptedMain bin/Test
	bin/ScriptedMain
	bin/Test

bin/ScriptedMain: ScriptedMain.swift
	mkdir -p bin/
	swiftc -D SCRIPTEDMAIN -o bin/ScriptedMain ScriptedMain.swift

ScriptedMain.swiftmodule: ScriptedMain.swift
	swiftc -emit-library -module-name ScriptedMain -emit-module ScriptedMain.swift

bin/Test: Test.swift ScriptedMain.swiftmodule
	mkdir -p bin/
	swiftc -D TEST -o bin/Test Test.swift -I "." -L "." -lScriptedMain -module-link-name ScriptedMain

clean:
	-rm -rf bin/
	-rm *.swiftmodule
	-rm *.swiftdoc
	-rm *.dylib

ScriptedMain.swift

import Foundation

public class ScriptedMain {
  public var meaningOfLife = 42

  public init() {}

  public class func main() {
    var meaning = ScriptedMain().meaningOfLife

    println("Main: The meaning of life is \(meaning)")
  }
}

#if SCRIPTEDMAIN
@objc class ScriptedMainAutoload {
  @objc class func load() {
    ScriptedMain.main()
  }
}
#endif

Test.swift

import Foundation
import ScriptedMain

public class Test {
  public class func main() {
    var meaning = ScriptedMain().meaningOfLife

    println("Test: The meaning of life is \(meaning)")
  }
}

#if TEST
@objc class TestAutoload {
  @objc class func load() {
    Test.main()
  }
}
#endif

Tcl

proc main {args} {
    puts "Directory: [pwd]"
    puts "Program: $::argv0"
    puts "Number of args: [llength $args]"
    foreach arg $args {puts "Arg: $arg"}
}

if {$::argv0 eq [info script]} {
    main {*}$::argv
}

UNIX Shell

Bash has scripted main.

scriptedmain.sh

#!/usr/bin/env sh

meaning_of_life() {
	return 42
}

main() {
	meaning_of_life
	echo "Main: The meaning of life is $?"
}

if [[ "$BASH_SOURCE" == "$0" ]]
then
    main
fi

test.sh

#!/bin/bash

path=$(dirname -- "$0")
source "$path/scriptedmain"

meaning_of_life
echo "Test: The meaning of life is $?"

Wren

As far as Wren is concerned, a modulino and an executable library seem to be different names for the same thing. This therefore uses the same technique as the Executable_library#Wren task to create a simple modulino.

Note that Wren doesn't need or normally use a main() function to start a script, though we use one here to make the example clearer.

First we create a module for our modulino:

/* Modulinos.wren */

var MeaningOfLife = Fn.new { 42 }

var main = Fn.new {
    System.print("The meaning of life is %(MeaningOfLife.call()).")
}

// Check if it's being used as a library or not.
import "os" for Process
if (Process.allArguments[1] == "Modulinos.wren") {  // if true, not a library
    main.call()
}

and run it to make sure it works OK when run directly:

Output:
The meaning of life is 42.

Next we create another module which imports the modulino:

/* Modulinos_main.wren */

import "./Modulinos" for MeaningOfLife

var main = Fn.new {
    System.print("Who says the meaning of life is %(MeaningOfLife.call())?")
}

main.call()

and run this to make sure the modulino's main() function doesn't run:

Output:
Who says the meaning of life is 42?

ZX Spectrum Basic

On the ZX Spectrum, there is no main function as such, however a saved program can be made to start running from a particular line number by providing the line number as a parameter to save command. If the program is being merged as a module, then it does not run automatically. The following example will save the program in memory so that it starts running from line 500:

SAVE "MYPROG" LINE 500: REM For a program with main code starting at line 500