<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2976610718577514012</id><updated>2024-10-24T01:02:43.805-07:00</updated><category term="F# Mono MacOSX Linux"/><title type='text'>SolvedDevProblems</title><subtitle type='html'>A recording of miscellaneous software development problems and their solutions for which I haven&#39;t found a good answer already posted somewhere.&#xa;&#xa;Any/all AdSense revenue will be donated to the Nature Conservancy or other registered not-for-profit organization.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://solveddevproblems.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://solveddevproblems.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jason McCampbell</name><uri>http://www.blogger.com/profile/07373769269519231469</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2976610718577514012.post-5430036030049851518</id><published>2011-03-27T11:19:00.000-07:00</published><updated>2011-03-27T11:19:18.771-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="F# Mono MacOSX Linux"/><title type='text'>Ordering files in MonoDevelop&#39;s F# Plug-in</title><content type='html'>I have been using Tomas Petricek&#39;s &lt;a href=&quot;http://functional-variations.net/monodevelop/&quot;&gt;F# Plug-in for MonoDevelop&lt;/a&gt; a lot recently for some personal projects. The addition of code-completion and on-the-fly compilation has been a nice upgrade from XCode.  Mostly it was working well until I added a new module and the main program file couldn&#39;t find it and just reported errors.  It built fine using my Makefiles.&lt;br /&gt;
&lt;br /&gt;
After looking at the compiler output I realized that the ordering of the files was wrong.  The F# compiler enforces strict, non-cyclic dependencies between files (modules) and requires the order of the files on the command line reflect this.  That is, the modules with no dependencies (except references) come first, and those dependent on the earlier ones come next. &lt;br /&gt;
&lt;br /&gt;
For example, assume we are building a .DLL with files A.fs, B.fs, and C.fs.  If files B and C are independent, but file A references both B and C then A must come after both B and C on the compile line:&lt;br /&gt;
&lt;ol class=&quot;code&quot;&gt;mono fsc.exe [references] B.fs C.fs A.fs&lt;/ol&gt;&lt;br /&gt;
I knew what the issue was but haven&#39;t been able to find a way in MonoDevelop to control this.  Finally while watching the Australian Grand Prix this morning I found it.  Experienced MonoDevelop users probably already know this, though it isn&#39;t necessary for C#, but I finally found the option to control the build order.&lt;br /&gt;
&lt;br /&gt;
Under the Project Options menu item (either Project Menu or the right-click popup menu), find the heading &#39;Build&#39; and click on the &#39;General&#39; item.  This brings up two tabs in the right-hand display both oddly named &#39;General&#39; as well. The second one controls the build order. Once I fixed the build order to reflect the file dependencies I closed and re-openened the editor tabs and all is well again!&lt;br /&gt;
&lt;br /&gt;
&lt;/href&gt;</content><link rel='replies' type='application/atom+xml' href='http://solveddevproblems.blogspot.com/feeds/5430036030049851518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://solveddevproblems.blogspot.com/2011/03/ordering-files-in-monodevelops-f-plug.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default/5430036030049851518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default/5430036030049851518'/><link rel='alternate' type='text/html' href='http://solveddevproblems.blogspot.com/2011/03/ordering-files-in-monodevelops-f-plug.html' title='Ordering files in MonoDevelop&#39;s F# Plug-in'/><author><name>Jason McCampbell</name><uri>http://www.blogger.com/profile/07373769269519231469</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2976610718577514012.post-6179208908747834879</id><published>2010-02-17T11:45:00.000-08:00</published><updated>2010-02-17T12:11:47.283-08:00</updated><title type='text'>F# Futures</title><content type='html'>I have been using F# a great deal lately.  It&#39;s one of those languages that, once I got past the syntax and back into thinking &quot;functional decomposition&quot; (as opposed to object-oriented decomposition), I was consistently surprised by how little code was required to solve a problem.  A lot like Python, but the runtime is considerably better.  Running on Mono it won&#39;t keep up with C++ but I would guess my productivity to be 2-3x higher in F#, which makes it appropriate for a bulk of the code.&lt;br /&gt;
&lt;br /&gt;
One issue I ran into early on is that async blocks are nice, but don&#39;t work well for computations that return a value.  What I was looking for was a way to opportunistically spawn off particular chunks of code to the thread pool and then retrieve the result at some join point. I have not yet found a way to do this with async blocks -- please let me know if I am mistaken.&lt;br /&gt;
&lt;br /&gt;
The Future type below works very much like the Lazy&lt;&gt; type, except that it queues the function to run in the thread pool immediately.  Calling the Value method returns the results, blocking until complete if necessary.  Exceptions in the function are trapped and re-raised when Value is called.&lt;br /&gt;
&lt;br /&gt;
One example where this is useful is when several intermediate results need to be computed before a final synchronizing point:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;pre&gt;let a = parseLogFile (setName + &quot;.log&quot;)
    let b = loadGpxDataSet (setName + &quot;.gpx&quot;)
    let c = loadElevationData areaBounds
    let model = ConstructModel a b c
&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this trivial example, the intermediate results for a, b, and c could be done in parallel. The future type makes this straightforward:&lt;br /&gt;
&lt;code&gt;&lt;pre&gt;let a = Future( fun () -&gt; parseLogFile (setName + &quot;.log&quot;) )
   let b = Future( fun () -&gt; loadGpxDataSet (setName + &quot;.gpx&quot;) )
   let c = Future( fun () -&gt; loadElevationData areaBounds )
   let model = ConstructModel a.Value b.Value c.Value
&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary:&lt;/b&gt;&lt;br /&gt;
Platform: .Net / Mono&lt;br /&gt;
Language: F#&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;pre&gt;&lt;span style=&quot;color: lightgreen&quot;&gt;
/// Provides basic functionality for parallelizing specific 
/// computations that produce a result to be used in the 
/// future.  Similar to async { } blocks but allows the main
/// thread to opportunistically spawn off computations 
/// instead of running the whole flow as an async block.&lt;/span&gt;
module Futures =
    open System.ComponentModel
    open System.Threading
    

    &lt;span style=&quot;color: lightgreen&quot;&gt;
    /// Executes a computation in a background worker and 
    /// synchronizes on the result return.  The computation 
    /// is started immediately and calling &#39;Value&#39; blocks 
    /// until the result is ready.&lt;/span&gt;
    type Future&lt;&#39;t&gt;(f : unit -&gt; &#39;t) =
        &lt;span style=&quot;color: lightgreen&quot;&gt;
        /// Result of the computation on normal exit.&lt;/span&gt;
        let mutable result :&#39;t option = None
        
        &lt;span style=&quot;color: lightgreen&quot;&gt;
        /// Result if an exception was thrown.&lt;/span&gt;
        let mutable ext : Exception option = None
        
        let syncRoot = new Object()
        
        &lt;span style=&quot;color: lightgreen&quot;&gt;
        /// Pulse object used to wait until a result 
        /// is ready.  ensurePulse() is used so we don&#39;t 
        /// have to create the object if the result is 
        /// done before it&#39;s needed.&lt;/span&gt;
        let mutable pulse : ManualResetEvent = null
        let ensurePulse() = 
            lock syncRoot (fun () -&gt;
                match pulse with 
                | null -&gt; 
                    pulse &lt;- new ManualResetEvent(false);
                | _ -&gt; 
                    ()
                pulse)
            
        &lt;span style=&quot;color: lightgreen&quot;&gt;
        /// WARNING: Call once a lock on syncRoot is already 
        /// held.  Pulses the wait notifier.  Safe if
        /// called after &#39;pulse&#39; is created but before 
        /// WaitOne is called.&lt;/span&gt;
        let notifyWaiters() = if pulse &lt;&gt; null then pulse.Set() |&gt; ignore
        
        let work = new BackgroundWorker()
  
        &lt;span style=&quot;color: lightgreen&quot;&gt;
        /// On RunWorkerAsync(), run specified function and 
        /// store result.  All exceptions must be trapped.&lt;/span&gt;      
        do work.DoWork.Add( fun args -&gt;
                                try 
                                    result &lt;- Some( f() )
                                with e -&gt;
                                    ext &lt;- Some e
                                lock syncRoot ( fun () -&gt; notifyWaiters()) )

        &lt;span style=&quot;color: lightgreen&quot;&gt;
        /// Start immediately / automatically.&lt;/span&gt;
        do work.RunWorkerAsync()
        
        &lt;span style=&quot;color: lightgreen&quot;&gt;
        /// Returns the value of the computation, blocking 
        /// if the result isn&#39;t ready yet.&lt;/span&gt;
        member t.Value =
            &lt;span style=&quot;color: lightgreen&quot;&gt;// If available, we can return it right away.&lt;/span&gt;
            match result with
            | Some x -&gt; x
            | None when ext.IsSome -&gt; raise (Option.get ext)
            | None -&gt;
                let p = ensurePulse()
                
                &lt;span style=&quot;color: lightgreen&quot;&gt;
                // Check again in case it changed while 
                // we were gettting the wait object.&lt;/span&gt;
                match result with
                | Some x -&gt; x
                | None -&gt;
                    &lt;span style=&quot;color: lightgreen&quot;&gt;
                    // Lock-free is ok because if the pulse.Set() 
                    // method is called between when we
                    // checked &#39;result&#39; and call WaitOne here, 
                    // WaitOne will return immediately.&lt;/span&gt;
                    p.WaitOne(1000000000) |&gt; ignore
                    match result with
                    | Some x -&gt; x
                    | None -&gt;
                        if ext.IsSome then raise (Option.get ext)
                        else failwith &quot;Future computation failed.&quot;
    
        &lt;span style=&quot;color: lightgreen&quot;&gt;
        /// Returns true if the computation is finished, false if not.&lt;/span&gt;
        member t.IsComplete =
            match result with
            | Some x -&gt; true
            | None when Option.isSome ext -&gt; true
            | None -&gt; false
&lt;/pre&gt;&lt;/code&gt;</content><link rel='replies' type='application/atom+xml' href='http://solveddevproblems.blogspot.com/feeds/6179208908747834879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://solveddevproblems.blogspot.com/2010/02/f-futures.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default/6179208908747834879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default/6179208908747834879'/><link rel='alternate' type='text/html' href='http://solveddevproblems.blogspot.com/2010/02/f-futures.html' title='F# Futures'/><author><name>Jason McCampbell</name><uri>http://www.blogger.com/profile/07373769269519231469</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2976610718577514012.post-975641062707735265</id><published>2010-02-17T06:57:00.001-08:00</published><updated>2010-02-17T06:57:56.171-08:00</updated><title type='text'>Introduction</title><content type='html'>Welcome.  This page is intended to be a simple recording of odd software development problems &amp; solutions that I have run into. These are problems for which I was unable to find a solution posted anywhere else and am posting here in attempt to give back to the community. As such I don&#39;t plan to at any specific frequency, just as I run into odd problems.&lt;br /&gt;
&lt;br /&gt;
Please feel free to comment publicly or email me privately with feedback, questions, whatever.&lt;br /&gt;
&lt;br /&gt;
Any/all AdSense revenue will be donated to The Nature Conservancy or other registered not-for-profit organization.  I just added to gain some experience with it.&lt;br /&gt;
&lt;br /&gt;
Best Regards,&lt;br /&gt;
Jason</content><link rel='replies' type='application/atom+xml' href='http://solveddevproblems.blogspot.com/feeds/975641062707735265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://solveddevproblems.blogspot.com/2010/02/introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default/975641062707735265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default/975641062707735265'/><link rel='alternate' type='text/html' href='http://solveddevproblems.blogspot.com/2010/02/introduction.html' title='Introduction'/><author><name>Jason McCampbell</name><uri>http://www.blogger.com/profile/07373769269519231469</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2976610718577514012.post-3761329422857097122</id><published>2010-02-17T06:57:00.000-08:00</published><updated>2010-02-17T06:57:22.473-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="F# Mono MacOSX Linux"/><title type='text'>Auto SQL generation during update requires a valid SelectCommand</title><content type='html'>While populating a Postgres DB, some updates (not all) updates failed with the following exception:&lt;br /&gt;
&lt;blockquote&gt;Auto SQL generation during Update requires a valid SelectCommand.&lt;br /&gt;
at System.Data.Common.DbDataAdapter.Update (System.Data.DataRow[] dataRows, System.Data.Common.DataTableMapping tableMapping) [0x00000]&lt;/blockquote&gt;&lt;br /&gt;
At first I thought it was due to having several update threads running, but even with a single thread running it still occurred.&lt;br /&gt;
&lt;br /&gt;
The error showed up under Mono 2.4.1 running on Ubuntu 9.10.  I was not seeing it under Mac OS running Mono 2.6.1 or Ubuntu 9.10 also running Mono 2.6.1.&lt;br /&gt;
&lt;br /&gt;
Upgrading to Mono 2.6.1 &lt;i&gt;seems&lt;/i&gt; to have fixed it, but I have also seen other odd exceptions specifically on that VM.  It&#39;s possible that the VM has other issues.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary:&lt;/b&gt;&lt;br /&gt;
Platform:    Ubuntu Linux 9.10, Mac OS Snow Leopard running Mono 2.4.1 and 2.6.1&lt;br /&gt;
Language:    F#&lt;br /&gt;
Solution:    Switching from Mono 2.4 to 2.6.1 appears to have solved it.</content><link rel='replies' type='application/atom+xml' href='http://solveddevproblems.blogspot.com/feeds/3761329422857097122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://solveddevproblems.blogspot.com/2010/02/auto-sql-generation-during-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default/3761329422857097122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2976610718577514012/posts/default/3761329422857097122'/><link rel='alternate' type='text/html' href='http://solveddevproblems.blogspot.com/2010/02/auto-sql-generation-during-update.html' title='Auto SQL generation during update requires a valid SelectCommand'/><author><name>Jason McCampbell</name><uri>http://www.blogger.com/profile/07373769269519231469</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>