pages tagged programming http://meng6net.localhost/tag/programming/ <p><small>Copyright © 2005-2020 by <code>Meng Lu &lt;lumeng3@gmail.com&gt;</code></small></p> Meng Lu's home page ikiwiki Mon, 11 May 2020 23:43:35 +0000 Nesting bullet lists in footnotes http://meng6net.localhost/test/Markdown_syntax_test/nesting_bullet_lists_in_footnotes/ http://meng6net.localhost/test/Markdown_syntax_test/nesting_bullet_lists_in_footnotes/ Markdown computing programming Mon, 11 May 2020 18:19:21 +0000 2020-05-11T23:43:35Z <p>Test paragraph<sup id="fnref:1"><a href="http://meng6net.localhost/tag/programming/#fn:1" rel= "footnote">1</a></sup>. Another sentence and some<sup id= "fnref:2"><a href="http://meng6net.localhost/tag/programming/#fn:2" rel="footnote">2</a></sup> word.</p> <div class="footnotes"> <hr /> <ol> <li id="fn:1"> <p>Footnote text</p> <ul> <li>One</li> <li>Two</li> </ul> <p>More text.</p> <pre><code>Code block. </code></pre> <a href="http://meng6net.localhost/tag/programming/#fnref:1" rev="footnote">↩</a></li> <li id="fn:2"> <p>Footnote text</p> <ul> <li>One</li> <li>Two</li> </ul> <p>More text.</p> <pre><code>Code block. </code></pre> <a href="http://meng6net.localhost/tag/programming/#fnref:2" rev="footnote">↩</a></li> </ol> </div> Haskell http://meng6net.localhost/journal/Haskell/ http://meng6net.localhost/journal/Haskell/ Haskell computing journal note programming Sat, 13 Oct 2018 03:56:52 +0000 2018-10-13T03:56:52Z <h2>Journal</h2> <h3>Entering multi-line code in GHCi</h3> <p>Use <code>:{</code> and <code>:}</code> to sandwich a block of code consisting of multiple lines:</p> <pre><code>Prelude&gt; :{ Prelude| incrementInteger :: Int -&gt; Int Prelude| incrementInteger x = x + 1 Prelude| :} Prelude&gt; incrementInteger 1 2 </code></pre> <h3>Using the latest released version of GHC with stack</h3> <p>Specify the version of LTS (i.e. Long Term Support) Haskell to use by default in `$HOME/.stack/global-project/stack.yaml:</p> <pre><code>resolver: lts-8.15 </code></pre> <p>As of May, 2017, the newest released version of LTS Haskell is 8.15. This version number can be found on https://www.haskell.org/downloads.</p> <h3><code>data</code>, <code>type</code>, and <code>newtype</code></h3> <ul> <li> <p>https://stackoverflow.com/a/33316715</p> </li> <li> <p>In GHCi, print the type of a symbol</p> <pre><code> Prelude&gt; :type Nothing Nothing :: Maybe a Prelude&gt; :type (+) (+) :: Num a =&gt; a -&gt; a -&gt; a Prelude&gt; :type print "Hello World" print "Hello World" :: IO () </code></pre></li> </ul> <h3><code>Nothing</code> and <a href= "https://wiki.haskell.org/Maybe"><code>Maybe</code></a></h3> <h3><a href="https://wiki.haskell.org/Partial_application">Partial application</a></h3> <p>Functions are not partial, but rather a function can be applied partially.</p> <h3>Function type decalaration</h3> <pre><code>myFunc :: type1 -&gt; type2 -&gt; type3 -&gt; type4 </code></pre> <h3><a href="https://wiki.haskell.org/Pure">Pure as in 'pure functional programming languages'</a></h3> <h3>Get information about a Haskell word in GHCi</h3> <pre><code>Prelude&gt; :info pure class Functor f =&gt; Applicative (f :: * -&gt; *) where pure :: a -&gt; f a ... -- Defined in ‘GHC.Base’ </code></pre> <h3><a href="https://stackoverflow.com/a/9221026">Concatenating multiple strings into one using <code>intercalate</code>, <code>intersperse</code> and <code>concat</code>, and <code>unword</code></a>.</h3> <h3>Function application takes precedence over any binary operator.</h3> <p>For example,</p> <pre> <code>ourPicture = colored green (solidCircle 1) &amp; solidCircle 2 </code></pre> <p>is equivalent to</p> <pre> <code>ourPicture = (colored green (solidCircle 1)) &amp; (solidCircle 2) </code></pre> <h3><a href= "http://learnyouahaskell.com/syntax-in-functions">guard</a></h3> <h3>Changing a prefixing function to an infix binary operator</h3> <pre><code>Prelude&gt; mod 3 2 1 Prelude&gt; 3 `mod` 2 1 </code></pre> <h3>Largest integer</h3> <pre><code>Prelude&gt; :{ Prelude| myInt :: Int Prelude| myInt = 2^63 - 1 Prelude| :} Prelude&gt; myInt 9223372036854775807 Prelude&gt; myInt + 1 -9223372036854775808 Prelude&gt; :{ Prelude| minInt :: Int Prelude| minInt = - 2^63 Prelude| :} Prelude&gt; minInt -9223372036854775808 Prelude&gt; minInt - 1 9223372036854775807 </code></pre> <h2>Arithmetic expression with different types of numbers</h2> <pre><code>Prelude&gt; :{ Prelude| d :: Double Prelude| i :: Int Prelude| d = 1.2 Prelude| i = 1 Prelude| :} Prelude&gt; d+i &lt;interactive&gt;:48:3: error: • Couldn't match expected type ‘Double’ with actual type ‘Int’ • In the second argument of ‘(+)’, namely ‘i’ In the expression: d + i In an equation for ‘it’: it = d + i Prelude&gt; d + fromIntegral i 2.2 Prelude&gt; </code></pre> <h2>References</h2> <ul> <li>https://www.stackage.org <ul> <li>Lookup basic information about a word, e.g. <code>pure</code>: https://www.stackage.org/lts-8.15/hoogle?q=pure</li> </ul> </li> </ul> Haskell http://meng6net.localhost/computing/programming/Haskell/ http://meng6net.localhost/computing/programming/Haskell/ Haskell computing note programming Sat, 13 Oct 2018 03:56:52 +0000 2018-10-13T03:56:52Z <h2>Misc</h2> <ul> <li>http://tryhaskell.org</li> </ul> <h2>Softwares</h2> <h3>IDE's</h3> <ul> <li>http://code.world/haskell, an online IDE to write and run Haskell code, e.g. https://code.world/haskell#Ptxn0dmOwm9z1xqIGrwPfzQ.</li> </ul> Wolfram http://meng6net.localhost/computing/programming/Wolfram/ http://meng6net.localhost/computing/programming/Wolfram/ Mathematica Wolfram computing note programming Sat, 20 May 2017 21:53:47 +0000 2017-05-21T06:06:00Z <h2>Programming idioms</h2> <h3>Caching the result of a time-comsuming computation in a symbol's <code>DownValue</code></h3> <pre><code>ClearAll[f] f[x_] := f[x] = (Pause[5]; Print["Time consuming definition run!"]; 1); In[31]:= DownValues[f] Out[31]= {HoldPattern[f[x_]]:&gt;(f[x]=(Pause[5];Print[Time consuming definition run!];1))} In[32]:= f[1]//AbsoluteTiming//Timing f[1]//AbsoluteTiming//Timing During evaluation of In[32]:= Time consuming definition run! Out[32]= {0.061456,{5.00291,1}} Out[33]= {7.*10^-6,{1.*10^-6,1}} In[34]:= DownValues[f] Out[34]= {HoldPattern[f[1]]:&gt;1,HoldPattern[f[x_]]:&gt;(f[x]=(Pause[5];Print[Time consuming definition run!];1))} </code></pre> Haskell and Wolfram Language syntax comparison http://meng6net.localhost/computing/programming/Haskell_and_Wolfram_Language_syntax_comparison/ http://meng6net.localhost/computing/programming/Haskell_and_Wolfram_Language_syntax_comparison/ Haskell Mathematica Wolfram computing note programming Fri, 19 May 2017 02:50:12 +0000 2017-05-22T20:24:50Z <table class="datatable"> <thead> <tr> <th>description</th> <th>Haskell</th> <th>Wolfram</th> <th colspan="2">comment</th> </tr> </thead> <tbody> <tr> <td>defining a named function with explicitly named arguments</td> <td> <pre> <code>incrementInteger :: Int -&gt; Int<br />incrementInteger n = n + 1</code></pre></td> <td> <pre><code>incrementInteger[n_Integer] := n + 1;</code></pre></td> <td colspan="2"></td> </tr> <tr> <td>defining a named function with lambda expression</td> <td> <pre> <code>incrementInteger :: Int -&gt; Int<br />incrementInteger = \n -&gt; n + 1</code></pre></td> <td> <pre> <code>incrementInteger = Function[{n}, n + 1];</code></pre></td> <td colspan="2"></td> </tr> <tr> <td>defining a function with a function name as one of the arguments</td> <td> <pre> <code>Prelude&gt; increment = \x -&gt; x+1<br />Prelude&gt; double = \x -&gt; 2*x<br />Prelude&gt; thenDouble someFunc = double . someFunc<br />Prelude&gt; thenDouble increment 3<br />8</code></pre></td> <td> <pre> <code>In[1]:= double = Function[x, 2<em>x];<br />increment = Function[x, x + 1];<br />thenDouble[someFunc_] := Composition[double, someFunc];<br /><br />In[4]:= thenDouble[increment]<br /><br />Out[4]= Function[x, 2 x]@</em>Function[x, x + 1]<br /><br />In[5]:= (thenDouble[increment])[3]<br /><br />Out[5]= 8<br /></code></pre></td> <td colspan="2"></td> </tr> <tr> <td>defining a function with locally definded intermediate functions</td> <td> <pre> <code>Prelude&gt; :{<br />Prelude&gt; myFunc1 x =<br />Prelude&gt; let y = sin x<br />Prelude&gt; in cos y<br />Prelude&gt; :}<br />Prelude&gt; myFunc1 pi<br />1.0<br /><br />Prelude&gt; :{<br />Prelude&gt; myFunc2 x =<br />Prelude&gt; cos y<br />Prelude&gt; where<br />Prelude&gt; y = sin x<br />Prelude&gt; :}<br />Prelude&gt; myFunc2 pi<br />1.0</code></pre></td> <td> <pre> <code>In[1]:= myFunc[x_]:=With[{f=Sin[x]},Cos[f]]<br />myFunc[Pi]<br />Out[2]= 1</code></pre></td> <td colspan="2">Alternatively, instead of using <code>With</code> (for symbolic replacement), <a href= "https://reference.wolfram.com/language/tutorial/BlocksComparedWithModules.html"> use <code>Module</code> (for lexical scoping) or <code>Block</code> (for dynamic scoping)</a>.</td> </tr> </tbody> </table> 《Learn You a Haskell for Great Good!》 study note http://meng6net.localhost/computing/programming/Learn_You_a_Haskell_for_Great_Good_reading_note/ http://meng6net.localhost/computing/programming/Learn_You_a_Haskell_for_Great_Good_reading_note/ Haskell book computing note programming to-do Thu, 18 May 2017 23:35:08 +0000 2017-05-18T23:35:08Z <h2>Introduction</h2> <ul> <li> <p>Haskell is a purely functional programming language.</p> </li> <li> <p>"In purely functional programming you don't tell the computer what to do as such but rather you tell it what stuff is. … You express that in the form of functions. … "</p> </li> <li> <p>A Haskell function cannot have side effects other than mapping its input to an output as a mathematical function.</p> </li> <li> <p>Haskell is lazy in that it does not compute anything until it have to in order to return a value.</p> </li> <li> <p>Haskell is statically typed.</p> <ul> <li>Type inference allows deducing the appropriate type automatically by inference on compatibility between the inputs and outputs.</li> </ul> </li> </ul> <h2>Starting out</h2> <h3>Ready, set, go!</h3> <ul> <li> <p><code>ghci</code>: The Glorious Glasgow Haskell Compilation System. Environment to interactively compile and run Haskell programs. Exit GHCi using <code>:quit</code>. <a href= "http://www.haskell.org/ghc/docs/5.04/html/users_guide/ghci.html">GHCi documentation</a>.</p> </li> <li> <p>Not-equal operator: <code>/=</code>.</p> </li> <li> <p>Compile-time error on incompatible types: <code>123 + "foobar"</code></p> </li> <li> <p>Compile a program: <code>ghci&gt; l:myprogram.hs</code>.</p> </li> <li> <p><code>'</code> is allowed in function name, e.g. <code>foo'Bar</code> is a valid function name.</p> </li> <li> <p>Function names cannot begin with a lower-case letter.</p> </li> </ul> <h3>An intro to lists</h3> <ul> <li> <p>In Haskell, a strings is a lists of characters.</p> </li> <li> <p>List and tuple syntax difference: <code>[1, 2]</code>, <code>(1, "foobar")</code>. A tuple can contain elements of different types, while a list cannot. This bears some similarity with Python's lists and tuples. A difference is that in Python, lists are mutable but tuples are not.</p> </li> <li> <p>Concatenate operation: <code>[1, 2] ++ [3, 4]</code>, <code>"foo" ++ "bar"</code>, <code>['a', 'b'] ++ ['c', 'd']</code>.</p> </li> <li> <p>[https://en.wikipedia.org/wiki/Cons cons] operation <code>:</code>:</p> <pre><code> Prelude&gt; 'f' : "bar" "fbar" Prelude&gt; 1: [3, 4] [1,3,4] Prelude&gt; </code></pre></li> <li> <p>If <code>"XXX...XXX"</code> is a very long string, <code>"XXX...XXX" ++ "foobar"</code> will be slow.</p> </li> <li> <p><code>[1, 2, 3]</code> equals <code>1 : 2 : 3 : []</code>.</p> </li> <li> <p>Take parts of a list: <code>[1, 3, 5, 7] !! 2</code> returns <code>5</code>. Haskell lists uses <a href= "https://en.wikipedia.org/wiki/Zero-based_numbering">zero-based numbering</a>. <code>take 2 [1, 3, 5, 7]</code> gives the third element <code>5</code>. <code>drop 2 [1, 3, 5, 7]</code> gives <code>[1, 3, 7]</code>. Compare this to Mathematica <code>{1,3,5,7}&lt;span class="createlink"&gt;3&lt;/span&gt;</code>, <code>Take[{1,3,5,7}, {3}]</code>, <code>Drop[{1,3,5,7}, {3}]</code>.</p> </li> <li> <p>Test element membership in a list: <code>elem 3 [2, 4, 6]</code> and <code>2 \</code>elem` [1, 3, 5, 7]`.</p> </li> <li> <p><code>[[1, 2], ["foo", "bar"]]</code> is invalid as the types of the elements of the two sub-lists are not same.</p> </li> <li> <p>Lists compare in <a href= "https://en.wikipedia.org/wiki/Lexicographical_order">lexicographical order</a>. E.g. <code>[1, 3, 4] &lt; [1, 4, 2]</code>.</p> </li> <li> <p><code>head [1, 2, 3]</code>, <code>tail [1, 2, 3]</code>, <code>init [1, 2, 3]</code>, <code>last [1, 2, 3]</code>. Compare with Mathematica / Wolfram Langauge namings: <code>First[{1,2,3}]</code>, <code>Rest[{1,2,3}]</code>, <code>Most[{1,2,3}]</code>, <code>Last[{1,2,3}]</code></p> </li> <li> <p><code>null [1, 2, 3]</code>, <code>null []</code></p> </li> </ul> <h2>Other side notes</h2> <ul> <li> <p>One of the key features and advantanges of Haskell is its purity: all side-effects are encapsulated in a monad.</p> </li> <li> <p>[https://en.wikipedia.org/wiki/Algebraic_data type Algebraic data type]:</p> <p>data List a = Nil | Cons a (List a)</p> <p>data Tree = Empty | Leaf Int | Node Tree Tree</p> </li> </ul> <p><code>Tree</code> is a <a href= "https://en.wikipedia.org/wiki/Tagged_union">sum data type</a> a.k.a. tagged union.</p> <p><code>Tree</code> is a <a href= "https://en.wikipedia.org/wiki/Recursive_data_type">recursive data type</a>.</p> <ul> <li> <p>Pattern matching in Haskell:</p> <pre><code> depth :: Tree -&gt; Int depth Empty = 0 depth (Leaf n) = 1 depth (Node l r) = 1 + max (depth l) (depth r) </code></pre></li> </ul> <h2>References</h2> <ul> <li> <p>https://ghcformacosx.github.io/</p> </li> <li> <p>Search a Haskell function by desired type signature, e.g. https://www.haskell.org/hoogle/?hoogle=String+-%3E+Int (And the desired function for turning an object to a <code>String</code> is possibly <code>read :: Read a =&gt; String -&gt; a</code>).</p> </li> </ul> Python division http://meng6net.localhost/journal/Python_division/ http://meng6net.localhost/journal/Python_division/ Python note programming tip Tue, 16 May 2017 23:59:39 +0000 2017-05-16T23:59:39Z <p>In Python 2, dividing two integers will yield a rounded integer result:</p> <pre><code>$ ipython2 Python 2.7.11 (default, Jan 22 2016, 08:29:18) Type "copyright", "credits" or "license" for more information. IPython 4.1.2 -- An enhanced Interactive Python. ? -&gt; Introduction and overview of IPython's features. %quickref -&gt; Quick reference. help -&gt; Python's own help system. object? -&gt; Details about 'object', use 'object??' for extra details. In [1]: 1/2 Out[1]: 0 </code></pre> <p>To get a real-number result:</p> <pre><code>In [2]: 1./2 Out[2]: 0.5 In [3]: float(1)/2 Out[3]: 0.5 </code></pre> <p>In Python 3, the default is the real-number result:</p> <pre><code>$ ipython Python 3.5.1 (default, Dec 7 2015, 21:59:10) Type "copyright", "credits" or "license" for more information. IPython 4.1.2 -- An enhanced Interactive Python. ? -&gt; Introduction and overview of IPython's features. %quickref -&gt; Quick reference. help -&gt; Python's own help system. object? -&gt; Details about 'object', use 'object??' for extra details. In [2]: 1/2 Out[2]: 0.5 In [3]: exit &gt;&gt;&gt; elapsed time 15s </code></pre> <p>In a Python script, to use Python 3 division behavior for Python 2:</p> <pre><code>import from __future__ division; print 1/2 </code></pre> Drawing polyhedra with textured faces in Mathematica http://meng6net.localhost/blog/drawing_polyhedra_with_textured_faces_in_Mathematica/ http://meng6net.localhost/blog/drawing_polyhedra_with_textured_faces_in_Mathematica/ blog computing geometry graphics mathematics note polyhedron programming Tue, 16 May 2017 23:59:39 +0000 2017-05-16T23:59:39Z <p>In Mathematica and Wolfram Language, with the feature called <a href= "https://reference.wolfram.com/language/ref/Texture.html">Texture</a> it's easy to draw 3D solids such as polyhedra with <a href= "https://en.wikipedia.org/wiki/Image_texture">image textures</a> on the surface such as the faces of polyhedra. When playing with this, I drew a <a href= "https://en.wikipedia.org/wiki/Rhombic_hexecontahedron">rhombic hexecontahedron</a> (<a href= "https://www.wolframalpha.com/input/?t=crmtb01&amp;f=ob&amp;i=rhombic+hexecontahedron">properties</a>), the logo of <a href= "https://www.wolframalpha.com/">Wolfram|Alpha</a> with national flags on its faces:</p> <p><a href= "http://meng6net.localhost/blog/drawing_polyhedra_with_textured_faces_in_Mathematica/image/rhombic_hexecontahedron__60-largest-countries-flags.png"> <img src= "http://meng6net.localhost/blog/drawing_polyhedra_with_textured_faces_in_Mathematica/900x-rhombic_hexecontahedron__60-largest-countries-flags.png" width="900" height="902" class="img" /></a></p> <p>☝ Rhombic hexecontahedron wrapped with the 60 most populous countries' national flags, one different flag drawn on each of the 60 rhombic faces. (It's somewhat odd that the most populous countries happen to have a lot of red and green colors in their national flags.)</p> <p>The code is in <a href= "https://github.com/lumeng/repo-meng-lib/blob/master/Mathematica/Notebook/polyhedra_with_textured_faces.nb"> my Git repository</a>.</p> <p>Remarks:</p> <ul> <li>It was a bit tricky to understand what the option <a href= "https://reference.wolfram.com/language/ref/VertexTextureCoordinates.html"> VertexTextureCoordinates</a> is and does, and how to set it up for what I'm trying to draw. It turns out for putting the national flags on the faces of a rhombic hexecontahedron, since both are (usually) isomorphic to a square, <code>VertexTextureCoordinates -&gt; {{0, 0}, {1, 0}, {1, 1}, {0, 1}}</code> is would work as it aligns the four vertices of a rectangular flag to the four vertices of a rhombic face.</li> </ul> <p>Something left to be improved:</p> <ul> <li> <p>Avoid flags that's not isomorphic to the face of the given polyhedron;</p> </li> <li> <p>Compute the suitable values of <code>VertexTextureCoordinates</code> to reduce or even avoid distortion of the flags;</p> </li> <li> <p>Find a reasonable way to align national flags of shapes not isomorphic to the shape of a face of a given polyhedron, such that the main feature of the national flag wrapped on a polyhedron face is well recognizable.</p> </li> </ul> /blog/drawing_polyhedra_with_textured_faces_in_Mathematica/#comments Munging data streams with functional programming and lambda expressions in Java 8 http://meng6net.localhost/blog/munging_data_streams_with_functional_programming_and_lambda_expressions_in_java/ http://meng6net.localhost/blog/munging_data_streams_with_functional_programming_and_lambda_expressions_in_java/ computing functional programming java note programming stream Tue, 16 May 2017 23:59:39 +0000 2017-05-16T23:59:39Z <p>With the advent of Java 8 and <a href= "http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html"> <code>java.util.stream</code></a> and <a href= "http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html"> lambda expressions</a> in it, one can do data munging in Java 8 as the following:</p> <p>Java 8:</p> <pre><code>public static void main(String[] args) { HashMap&lt;Integer, Character&gt; nucleobases = new HashMap&lt;&gt; (); nucleobases.put(1, 'A'); nucleobases.put(2, 'G'); nucleobases.put(3, 'T'); nucleobases.put(4, 'C'); range(0, 100) // generate a stream containing random strings of length 10 .mapToObj(i -&gt; randomNucleicAcidSequence(new Random(), nucleobases, 10)) // sort the elements in the stream to natural ordering .sorted() // group strings into sub-lists and wrap them into a stream .collect(groupingBy(name -&gt; name.charAt(0))) // print each sub-list's common initial letter and the constituent strings .forEach((letter, names) -&gt; System.out.println(letter + "\n\t" + names.stream().collect(joining("\n\t")))); } public static String randomNucleicAcidSequence(Random r, Map&lt;Integer, Character&gt; map, int length) { return r.ints(1, 4).limit(length).mapToObj( x -&gt; Character.toString(map.get(x))).collect(Collectors.joining()); } </code></pre> <p><a href= "https://github.com/lumeng/repogit-java-stream-basic-example">↑ Code in GitHub</a></p> <p>This is remarkbly similar to a program written in Mathematica using the <a href= "http://meng6net.localhost/computing/munging_style_for_mathematica_code_layout">munging style</a> I use all the time:</p> <pre><code>(* There is not a built-in RandomString[…] *) nucleobases = {"A", "G", "T", "C"}; randomNucleicAcidSequence[length_Integer] := StringJoin[nucleobases[[#]] &amp; /@ RandomInteger[{1, 4}, length]] Composition[ Print[StringJoin[{#[[1]],":\n",StringJoin[Riffle[#[[2]],"\n"]]}]]&amp; /@ # &amp;, (First[Characters[Part[#, 1]]]-&gt; #) &amp; /@ # &amp;, GatherBy[#, First[Characters[#]]&amp;]&amp;, Sort, Map[Function[{i}, randomNucleicAcidSequence[10]], #] &amp; ][Range[0, 100]] </code></pre> <p>The output of both program print the mucleic acid sequences grouped by initial neuclobase:</p> <pre><code>A: AAAATACCTC AAATAATCAT AACAGATACG ACAACTACGG ACCATCAAAT ... C: CAACGGGGTT CAAGAAGAGC CACACCCACA CACACTCTAC CAGGACCGGA ... G: GAACGTTTCA GAACTAAGCG GACCAGTTCT GAGAACACGT GAGCCGCCAC ... T: TAAAATTGCC TAAGGTGAGG TAGCCGGTTA TAGGCGGTGA TAGTTCGAGC ... </code></pre> <p>Data streams and <a href= "https://en.wikipedia.org/wiki/Streaming_algorithm">algorithms</a> for processing them is a recently hot research area in computer science. It seems to me it will be natural for Java standard library to include more and more stream algorithms in future.</p> <p><big>Related</big>:</p> <ul> <li><a href= "http://meng6net.localhost/tag/computing/munging_style_for_mathematica_code_layout/">Munging style for Mathematica code layout</a></li> </ul> /blog/munging_data_streams_with_functional_programming_and_lambda_expressions_in_java/#comments Munging style for Mathematica code layout http://meng6net.localhost/computing/munging_style_for_mathematica_code_layout/ http://meng6net.localhost/computing/munging_style_for_mathematica_code_layout/ computing mathematica note programming tip Tue, 16 May 2017 23:59:39 +0000 2017-05-16T23:59:39Z <p>This is a description to a programming and code formatting style for Mathematica programs that I call "munging style code layout".</p> <p>Any self-contained part of a Mathematica program is a Mathematica expression. As the oft-mentioned idiom said, in Mathematica, "everything is an expression". The appearance of a Mathematica expression is <code>function[arg1, arg2, ...]</code> ("functions", composite expressions) or simply <code>foobar</code> ("symbols", atomic expressions). This is true for any part of a Mathematica program at any depth.</p> <p>Any Mathematica function is essentially a nested structure of the above building blocks. Complex Mathematica program tends to have deeply nested expressions like</p> <pre> <code>f4[arg41, f3[arg31, arg32, f2[arg21, f1[input], ...], ...], arg43, ...] (* comment explaining what f1, f2, f3, f4 does *) </code></pre> <p>Imagine a complex Mathematica program having hundreds of above expressions, sometimes nesting each other. It is hard to read or understand code formatted this way because one needs to constantly jumping out and back into the brackets <code>[ ... ]</code>. This is a <a href= "https://en.wikipedia.org/wiki/Stack_(abstract_data_type">stack</a>) data structure stored in one's brain that one has to frequently navigate.</p> <p>Over the time I have gradually established a particular formatting style for complex Mathematica functions with such deep nested structure. I think it helps writing and understanding my Mathematica programs. I call it <strong>munging style code layout</strong>. It's nothing but putting small parts of the code onto separate lines and use <a href= "http://reference.wolfram.com/mathematica/ref/Composition.html"><code> Composition</code></a> to chain them up:</p> <pre><code>Composition[ f4[arg41, #, arg43, ...]&amp;, (* comment for what f4 does *) f3[arg31, arg32, #, ...]&amp;, (* comment for what f3 does *) f2[arg21, #, ...]&amp;, (* comment for what f2 does *) f1 (* comment for what f1 does *) ][input] </code></pre> <p>I call it <a href= "http://en.wikipedia.org/wiki/Mung_(computer_term)"><em>munging</em></a> because it overall operates on a compact initial input argument, typically represented by a Mathematica symbol, and process it step by step and little by little, for multiple steps before returning a final desired output.</p> <p>This way of laying out the code has a few advantages:</p> <ol> <li> <p>The program body will spread out to multiple lines naturally according to each step's logic. The code is still logically nested, but not visually nested.</p> </li> <li> <p>Each munging step can be commented at the end of line, so it's easier to write and read the comment. One line of code is structurally and logically simple, so each line's comment will be short too. As a result, the comments for the complete program should also be easier to read and understand.</p> </li> <li> <p>It is easier to write and debug code. A typical scenario is</p> </li> </ol> <p>Write the first simple step</p> <pre><code>Composition[ f1[arg11, #, arg13]&amp; (* comment for what f1 does *) ][input] </code></pre> <p>Run it and verify the first step does what it should do, then add a second step, and comment as you code:</p> <pre><code>Composition[ f2[arg21, #, ...]&amp;, (* comment for what f2 does *) f1[arg11, #, arg13]&amp; (* comment for what f1 does *) ][input] </code></pre> <p>Notice, when writing the body of <code>f2[...]</code>, one needs <em>not</em> to edit <em>around</em> <code>f1[....]</code>, but on a separate new line. This may not sound like a big deal, but, according to my personal experience, it eliminates a lot of chances of messing up with <code>f1[...]</code> when typing <code>f2[...]</code>. If one decides the <code>f2</code> just typed down shouldn't stay, he can just simply select the whole line of of <code>f2</code> -- typically a keyboard-only operation or a mouse-only operation depending on the programmer's habit and the editor -- and delete it without worrying about messing up any part of <code>f1[...]</code> or needing to copy <code>f1[...]</code> out safely. So there is an ergonomic advantage to separate <code>f1[...]</code> and <code>f2[...]</code> into different lines. You write your code in small chunks, and manage the chunks as compositing terms of the entire logic.</p> <p>In addition, one can easily print out the intermediate value in-between two steps by simply inserting a NOP step:</p> <pre><code>Composition[ f2[arg21, #, ...]&amp;, (* comment for what f2 does *) (Print@#; #)&amp;, (* NOP step to print out intermediate value for debugging *) f1 (* comment for what f1 does *) ][input] </code></pre> <p>When you have more steps added, you might find the first few steps aren't perfect, now you can insert NOP step to print out more intermediate values:</p> <pre><code>Composition[ ..., f4[arg41, #, arg43, ...]&amp;, (* comment for what f4 does *) (Print@#; #)&amp;, f3[arg31, arg32, #, ...]&amp;, (* comment for what f3 does *) (Print@#; #)&amp;, f2[arg21, #, ...]&amp;, (* comment for what f2 does *) f1 (* comment for what f1 does *) ][input] </code></pre> <p>Notice inserting these NOP steps again doesn't require editing at lines of the actual code (<code>f1[...]&amp;</code>, <code>f2[...]&amp;</code>, ...). So there is natural and convenient separation of debugging code and real code.</p> <p>All of this may appear to be too trivial a matter to document. But I found Mathematica code is harder to format than most other programming languages, partially because the character of Mathematica language (functional and symbolic) and partially because neither Mathematica notebook nor Wolfram Workbench provides sophisticated and robust automatic code formatting/indentation. This little formatting rule seems to help me writing better Mathematica code, sometimes also faster and easier in doing so.</p> <p><big>Related:</big></p> <ul> <li><a href= "http://meng6net.localhost/tag/blog/munging_data_streams_with_functional_programming_and_lambda_expressions_in_java/"> Munging data streams with functional programming and lambda expressions in Java 8</a></li> </ul>