Executable library: Difference between revisions
Content added Content deleted
(Add Nimrod) |
m ({{out}} / -Category:Scala Implementations) |
||
Line 1: | Line 1: | ||
{{task}} |
{{task}} |
||
⚫ | |||
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. |
|||
⚫ | |||
⚫ | |||
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. |
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> |
|||
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, |
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. |
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. |
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.) |
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 |
|||
⚫ | |||
for libraries versus commands in Inferno; |
|||
⚫ | |||
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>: |
Lib package in file <code>Hailstone.pm</code>: |
||
<lang perl>package Hailstone; |
|||
sub seq { |
sub seq { |
||
Line 945: | Line 964: | ||
}</lang> |
}</lang> |
||
{{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 |
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. |
|||
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 |
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) |
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. |
|||
<br>If not there, the REXX interpreter normally checks the |
|||
⚫ | |||
<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''' (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''' (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 '''EXEC'''. 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 '''EXEC'''. 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: : '''HAIL_PGM.REX''' and is stored in the current directory. |
The following program is named: : '''HAIL_PGM.REX''' 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 |
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. |
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 |
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 |
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> |
||
⚫ | |||
⚫ | |||
⚫ |