Executable library: Difference between revisions

Content added Content deleted
(Add Nimrod)
Line 1: Line 1:
{{task}}
{{task}}
{{omit from|Go}}
The general idea behind an executable library is to create a library that when used as a library does one thing; but has the ability to be run directly via command line. Thus the API comes with a CLI in the very same source code file.
{{omit from|GUISS}}
{{omit from|Maxima}}

The general idea behind an executable library is to create a library
that when used as a library does one thing;
but has the ability to be run directly via command line.
Thus the API comes with a CLI in the very same source code file.


'''Task detail'''
'''Task detail'''
Line 21: Line 28:
=={{header|Ada}}==
=={{header|Ada}}==


In Ada, '''any parameterless procedure''' can either '''run as a (stand-alone) main program''', or can '''be called from another program''' like a library function. For the task at hand, this appears useful -- except for the following two obstacles:
In Ada, '''any parameterless procedure''' can either '''run as a (stand-alone) main program''', or can '''be called from another program''' like a library function.
For the task at hand, this appears useful -- except for the following two obstacles:


1. There are neither ingoing parameters into a parameterless procedure, nor is there a return value.
1. There are neither ingoing parameters into a parameterless procedure, nor is there a return value.
Line 88: Line 96:
end Hailstone;</lang>
end Hailstone;</lang>


If we compile this and run it, we get the following output.
If we compile this and run it, we get the following output:

<pre>> ./hailstone
<pre>> ./hailstone
Hailstone( 27 ) = ( 27, 82, 41, 124, ..., 8, 4, 2, 1 ); Length: 112
Hailstone( 27 ) = ( 27, 82, 41, 124, ..., 8, 4, 2, 1 ); Length: 112
Line 138: Line 145:


Compiling and running this gives the following output:
Compiling and running this gives the following output:

<pre>> ./hailstone_test
<pre>> ./hailstone_test
Most frequent length: 72; 1467 sequences of that length.
Most frequent length: 72; 1467 sequences of that length.
Line 177: Line 183:
until n=1
until n=1
return out
return out
}</lang>
}</lang>Running this directly gives the output:
Running this directly gives the output:
<pre>Length of hailstone 27: 112
<pre>Length of hailstone 27: 112
Starts with 27, 82, 41, 124
Starts with 27, 82, 41, 124
Line 202: Line 209:
highestCount := count, highestN := length
highestCount := count, highestN := length
MsgBox % "the most common length was " highestN "; it occurred " highestCount " times."</lang>
MsgBox % "the most common length was " highestN "; it occurred " highestCount " times."</lang>
Running this '''does not''' trigger the output of the hailstone.ahk, instead it outputs this:
Running this '''does not''' trigger the output of the hailstone.ahk,
instead it outputs this:
<pre>the most common length was 72; it occurred 1467 times.</pre>
<pre>the most common length was 72; it occurred 1467 times.</pre>
[[Link title]]
[[Link title]]
Line 208: Line 216:
=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
To meet the terms of this task the BBC BASIC run-time engine '''bbcwrun.exe''' must be installed on the target PC and the file extension '''.bbc''' must be associated with this executable. This is normally the case when ''BBC BASIC for Windows'' has been installed.
To meet the terms of this task the BBC BASIC run-time engine '''bbcwrun.exe''' must be installed on the target PC and the file extension '''.bbc''' must be associated with this executable.
This is normally the case when ''BBC BASIC for Windows'' has been installed.

===Library===
===Library===
This must be saved as the file HAILSTONE.BBC. It may be used as a library (see below) or executed directly.
This must be saved as the file HAILSTONE.BBC.
It may be used as a library (see below) or executed directly.
<lang bbcbasic> seqlen% = FNhailstone(27)
<lang bbcbasic> seqlen% = FNhailstone(27)
PRINT "Sequence length for 27 is "; seqlen%
PRINT "Sequence length for 27 is "; seqlen%
Line 232: Line 243:
ENDWHILE
ENDWHILE
= L% + 1</lang>
= L% + 1</lang>
{{out}}
'''Output:'''
<pre>
<pre>
Sequence length for 27 is 112
Sequence length for 27 is 112
Line 238: Line 249:
Its sequence length is 351
Its sequence length is 351
</pre>
</pre>

===Client===
===Client===
This uses the above program as a library:
This uses the above program as a library:
Line 258: Line 270:
PRINT "It occurs " ; max% " times"
PRINT "It occurs " ; max% " times"
END</lang>
END</lang>
{{out}}
'''Output:'''
<pre>
<pre>
The most common sequence length is 72
The most common sequence length is 72
Line 534: Line 546:


Running it might look like this:
Running it might look like this:

<lang j> load jpath '~temp/66.ijs'
<lang j> load jpath '~temp/66.ijs'
Finding most frequent hailstone sequence length for
Finding most frequent hailstone sequence length for
Line 540: Line 551:
72</lang>
72</lang>


Notes: <code>9!:29]1</code> tells the interpeter to run a phrase. <code>9!:27'phrase'</code> tells the interpeter the phrase to execute. (<code>9!:</code> means, in essence: standard library number 9, and <code>9!:29</code> identifies a specific entry point in that library.) In 66.ijs we can not use the presence of <code>9!:29]1</code> from <code>hailseq.ijs</code> because hailseq.ijs was loaded with require which means that if it had already been loaded it will not be loaded again. (And, <code>66</code> here is just an arbitrary temporary file name.)
Notes: <code>9!:29]1</code> tells the interpeter to run a phrase. <code>9!:27'phrase'</code> tells the interpeter the phrase to execute. (<code>9!:</code> means, in essence: standard library number 9, and <code>9!:29</code> identifies a specific entry point in that library.)
In 66.ijs we can not use the presence of <code>9!:29]1</code> from <code>hailseq.ijs</code> because hailseq.ijs was loaded with require which means that if it had already been loaded it will not be loaded again.
(And, <code>66</code> here is just an arbitrary temporary file name.)


=={{header|Limbo}}==
=={{header|Limbo}}==


There's no real difference in compilation or output
There's no real difference in compilation or output for libraries versus commands in Inferno; commands (by convention) are expected to define an <code>init()</code> function that accepts a reference to a graphical context and a list of strings (i.e., the argument list) in order to satisy the type-checker. So this task is fairly simple. First, <code>execlib.b</code> looks like this:
for libraries versus commands in Inferno;
commands (by convention) are expected to define an <code>init()</code> function that accepts a reference to a graphical context and a list of strings (i.e., the argument list) in order to satisy the type-checker.
So this task is fairly simple.
First, <code>execlib.b</code> looks like this:


<lang Limbo>implement Execlib;
<lang Limbo>implement Execlib;
Line 761: Line 778:
echo "hailstone(n) where 1<=n<100000, is ", val, ". It occurs ", cnt, " times."</lang>
echo "hailstone(n) where 1<=n<100000, is ", val, ". It occurs ", cnt, " times."</lang>


{{out}}
'''Example output'''
<pre>The length of hailstone sequence that is most common for
<pre>The length of hailstone sequence that is most common for
hailstone(n) where 1<=n<100000, is 72. It occurs 1467 times.</pre>
hailstone(n) where 1<=n<100000, is 72. It occurs 1467 times.</pre>

=={{header|Perl}}==
=={{header|Perl}}==
Lib package in file <code>Hailstone.pm</code>:<lang perl>package Hailstone;
Lib package in file <code>Hailstone.pm</code>:
<lang perl>package Hailstone;


sub seq {
sub seq {
Line 945: Line 964:
}</lang>
}</lang>


Output for both examples:
{{out}} for both examples:
<pre>
most common length 72 appears 1467 times
most common length 72 appears 1467 times
</pre>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
There is no formal difference between libraries and other executable files in PicoLisp. Any function in a library can be called from the command line by prefixing it with '-'. Create an executable file (chmod +x) "hailstone.l":
There is no formal difference between libraries and other executable files
in PicoLisp.
Any function in a library can be called from the command line
by prefixing it with '-'.
Create an executable file (chmod +x) "hailstone.l":
<lang PicoLisp>#!/usr/bin/picolisp /usr/lib/picolisp/lib.l
<lang PicoLisp>#!/usr/bin/picolisp /usr/lib/picolisp/lib.l


Line 1,030: Line 1,055:
Both files could be in the same directory. (That is the easiest way to make the library known to its importer for this example)
Both files could be in the same directory. (That is the easiest way to make the library known to its importer for this example)


{{out}}
'''Sample output'''

On executing the file common_hailstone_length.py it loads the library and produces the following result:
On executing the file common_hailstone_length.py it loads the library and produces the following result:
<pre>The length of hailstone sequence that is most common for
<pre>The length of hailstone sequence that is most common for
Line 1,048: Line 1,072:
is one. When a file is used as a library (with <tt>require</tt>), the toplevel
is one. When a file is used as a library (with <tt>require</tt>), the toplevel
expressions are executed as well, but the <tt>main</tt> is <em>not</em>
expressions are executed as well, but the <tt>main</tt> is <em>not</em>
executed.
executed. The idea is that toplevel expressions might be used to initialize
The idea is that toplevel expressions might be used to initialize state
state that the library needs -- a good example here is the initialization of
the memoization hash table. (Note that this is better than the common hacks of
that the library needs -- a good example here is the initialization
of the memoization hash table.
check-the-loaded-script-name, since it is robust against failures due to
symlinks, case normalization, etc etc.)
(Note that this is better than the common hacks of check-the-loaded-script-name, since it is robust against failures due to symlinks, case normalization, etc etc.)


We start with a "<tt>hs.rkt</tt>" file that has the exact code from the
We start with a "<tt>hs.rkt</tt>" file that has the exact code from the
Line 1,081: Line 1,105:
N (car longest) (cdr longest)))
N (car longest) (cdr longest)))
</lang>
</lang>

Running it directly produces the same output as [[Hailstone sequence#Racket]]:
Running it directly produces the same output as [[Hailstone sequence#Racket]]:
<pre>
<pre>
Line 1,113: Line 1,138:
=={{header|REXX}}==
=={{header|REXX}}==
===task 1===
===task 1===
The following REXX subroutine (or function, as it returns a value) is normally stored in a folder that the REXX interpreter searches first for subroutine/function call/invokes.
The following REXX subroutine (or function, as it returns a value)
is normally stored in a folder that the REXX interpreter
<br>If not there, the REXX interpreter normally checks the current drive (or default disk), and then through some sort of heirarchy --- depending upon the particular REXX interpreter and operating system.
searches first for subroutine/function call/invokes.
<br>If not there, the REXX interpreter normally checks the
current drive (or default disk), and then through some sort of heirarchy --- depending upon the particular REXX interpreter and operating system.
<br><br>On Microsoft Windows systems using Regina, PC/REXX, Personal REXX, R4, or ROO, the program name is normally the function name with a file extension of '''REX''' &nbsp; (but that isn't a strict requirement or rule, each REXX interpreter has multiple file extensions that are supported).
<br><br>On Microsoft Windows systems using Regina, PC/REXX, Personal REXX, R4, or ROO, the program name is normally the function name with a file extension of '''REX''' &nbsp; (but that isn't a strict requirement or rule, each REXX interpreter has multiple file extensions that are supported).
<br>On VM/CMS systems, the filetype (the file extension) is normally &nbsp; '''EXEC'''. &nbsp; If however, the REXX program was previously '''EXECLOAD'''ed, it may have a different name (identity) assigned to it.
<br>On VM/CMS systems, the filetype (the file extension) is normally &nbsp; '''EXEC'''. &nbsp; If however, the REXX program was previously '''EXECLOAD'''ed, it may have a different name (identity) assigned to it.
Line 1,128: Line 1,156:
end /*while*/
end /*while*/
return s</lang>
return s</lang>

===task 2, 3===
===task 2, 3===
The following program is named: &nbsp;: '''HAIL_PGM.REX''' &nbsp; and is stored in the current directory.
The following program is named: &nbsp;: '''HAIL_PGM.REX''' &nbsp; and is stored in the current directory.
Line 1,146: Line 1,175:
say '(between 1──►99,999) ' bigJ 'has the longest hailstone sequence:' w
say '(between 1──►99,999) ' bigJ 'has the longest hailstone sequence:' w
/*stick a fork in it, we're done.*/</lang>
/*stick a fork in it, we're done.*/</lang>
{{out}}
'''output'''
<pre style="overflow:scroll">
<pre style="overflow:scroll">
27 has a hailstone sequence of 112 and starts with: 27 82 41 124 and ends with: 8 4 2 1
27 has a hailstone sequence of 112 and starts with: 27 82 41 124 and ends with: 8 4 2 1
Line 1,170: Line 1,199:
' is the most common hailstone sequence length (with' occ "occurrences)."
' is the most common hailstone sequence length (with' occ "occurrences)."
/*stick a fork in it, we're done.*/</lang>
/*stick a fork in it, we're done.*/</lang>
{{out}}
'''output'''
<pre style="overflow:scroll">
<pre style="overflow:scroll">
(between 1──►99999) 72 is the most common hailstone sequence length (with 1467 occurrences).
(between 1──►99999) 72 is the most common hailstone sequence length (with 1467 occurrences).
Line 1,190: Line 1,219:


=={{header|Ruby}}==
=={{header|Ruby}}==
An executable library checks ''__FILE__ == $0''. Here, ''__FILE__'' is the path of the current source file, and ''$0'' is the path of the current executable. If ''__FILE__ == $0'', then the current source file is the executable, else the current source file is a library for some other executable.
An executable library checks ''__FILE__ == $0''. Here, ''__FILE__'' is the path
of the current source file, and ''$0'' is the path of the current executable.
If ''__FILE__ == $0'', then the current source file is the executable,
else the current source file is a library for some other executable.


* ''__FILE__ == $0'' also works with older versions of Ruby, but this Hailstone example calls new methods in Ruby 1.8.7.
* ''__FILE__ == $0'' also works with older versions of Ruby, but this Hailstone example calls new methods in Ruby 1.8.7.
Line 1,225: Line 1,257:
end</lang>
end</lang>


It runs like any Ruby program:
{{out|It runs like any Ruby program}}

<pre>$ ruby scratch.rb
<pre>$ ruby scratch.rb
[112, [27, 82, 41, 124], [8, 4, 2, 1]]
[112, [27, 82, 41, 124], [8, 4, 2, 1]]
Line 1,246: Line 1,277:
puts "with #{count} such sequences."</lang>
puts "with #{count} such sequences."</lang>


As with any library, ''hailstone.rb'' must be in <code>$:</code>, the search path for libraries. One way is to leave ''hailstone.rb'' in the current directory and run <code>ruby -I. hsfreq.rb</code>. (Ruby older than 1.9.2 also searches the current directory by default.)
As with any library, ''hailstone.rb'' must be in <code>$:</code>, the search path for libraries.
One way is to leave ''hailstone.rb'' in the current directory and run <code>ruby -I. hsfreq.rb</code>.
(Ruby older than 1.9.2 also searches the current directory by default.)


<pre>$ ruby -I. hsfreq.rb
<pre>$ ruby -I. hsfreq.rb
Line 1,254: Line 1,287:


=={{header|Scala}}==
=={{header|Scala}}==
[[Category:Scala Implementations]]
{{libheader|Scala}}
{{libheader|Scala}}
In Scala it is possible to combine several "main"s (mixed-in by the App trait) in one file (e.g. HailstoneSequence.scala):
In Scala it is possible to combine several "main"s
(mixed-in by the App trait) in one file (e.g. HailstoneSequence.scala):
<lang Scala>object HailstoneSequence extends App { // Show it all, default number is 27.
<lang Scala>object HailstoneSequence extends App { // Show it all, default number is 27.
def hailstone(n: Int): Stream[Int] =
def hailstone(n: Int): Stream[Int] =
Line 1,310: Line 1,343:


C:\Users\FransAdm\Documents></pre>
C:\Users\FransAdm\Documents></pre>

=={{header|Tcl}}==
=={{header|Tcl}}==
The standard idiom for detecting whether a script is being loaded as a library or run directly is to compare the result of <code>info script</code> (which describes the name of the currently sourced script file) and the global <code>argv0</code> variable (which holds the name of the main script).
The standard idiom for detecting whether a script is being loaded as a library or run directly is to compare the result of <code>info script</code> (which describes the name of the currently sourced script file) and the global <code>argv0</code> variable (which holds the name of the main script).
Line 1,338: Line 1,372:
}</lang>
}</lang>


To make the package locatable, run this Tcl script in the same directory which builds the index file:
To make the package locatable, run this Tcl script
in the same directory which builds the index file:
<lang tcl>pkg_mkIndex .</lang>
<lang tcl>pkg_mkIndex .</lang>


Line 1,358: Line 1,393:


puts "most common length is $mostCommonLength, with frequency $freq"</lang>
puts "most common length is $mostCommonLength, with frequency $freq"</lang>

{{omit from|Go}}
{{omit from|GUISS}}
{{omit from|Maxima}}