Category Archives: Uncategorized

Haskell interlude

Okay, wordpress sux majorly; it kept messing this up every time I tried to post.

I’ll just have to write a successor to WordPress in Haskell (starting with clckwrks?) … sigh… (if I have time to rewrite every major piece of software in the world…)

I’ll probably post some SQL, PowerShell, or even maybe DAX soon (when I get deeper into DAX). Or at least F#. But here’s some Haskell that shows how concisely a binary-file-decoding task can be concisely-written.

The story: Years ago, I write a sort of Scrabble-cheat program called anagram ( http://my.streetpulse.com/shared/anagram.zip ) . It does a brute-force search of a word list to find all possible anagrams of the given rackletters, including blanks (repeatedly, due to careless coding, and to avoid having to implement a sort, or bucketization, or memory-allocation.) To save RAM, I encoded the word-list enable1.txt with what I called “prefix-compression”, meaning that if you have aardvark first, then aaple next, the encoded file just stores “ple” for the second word, with a byte-sized integer 2 to indicate that two characters can be copied from the previous word. This encoding can be decoded with scanl as-follows:
<pre>I’ll probably post some SQL, PowerShell, or even maybe DAX soon (when I get deeper into DAX). Or at least F#. But here’s some Haskell that shows how concisely a binary-file-decoding task can be concisely-written.

The story: Years ago, I write a sort of Scrabble-cheat program called anagram ( http://my.streetpulse.com/shared/anagram.zip ) . It does a brute-force search of a word list to find all possible anagrams of the given rackletters, including blanks (repeatedly, due to careless coding, and to avoid having to implement a sort, or bucketization, or memory-allocation.) To save RAM, I encoded the word-list enable1.txt with what I called “prefix-compression”, meaning that if you have aardvark first, then aaple next, the encoded file just stores “ple” for the second word, with a byte-sized integer 2 to indicate that two characters can be copied from the previous word. This encoding can be decoded with scanl as-follows:</pre>
<pre>I’ll probably post some SQL, PowerShell, or even maybe DAX soon (when I get deeper into DAX). Or at least F#. But here’s some Haskell that shows how concisely a binary-file-decoding task can be concisely-written.

The story: Years ago, I write a sort of Scrabble-cheat program called anagram ( http://my.streetpulse.com/shared/anagram.zip ) . It does a brute-force search of a word list to find all possible anagrams of the given rackletters, including blanks (repeatedly, due to careless coding, and to avoid having to implement a sort, or bucketization, or memory-allocation.) To save RAM, I encoded the word-list enable1.txt with what I called “prefix-compression”, meaning that if you have aardvark first, then aaple next, the encoded file just stores “ple” for the second word, with a byte-sized integer 2 to indicate that two characters can be copied from the previous word. This encoding can be decoded with scanl as-follows:

I tried <pre> and <blockquote> in html editing mode but couldn’t get this indented code to save properly; WordPress cuts it off every time.  Maybe I’ll post it to github.com/tallpeak … ahh, that’s nice; here it is:

https://gist.github.com/tallpeak/24dabfce6b5bf901d0e31eab0ca30aef

Why functional-programming?

Why am I fascinated with functional-programming, denotational-semantics, denotational-design, type-driven-design, etc?

Is it just because I’m more interested in more-reliable software? No.

Is it because I want easier-to-read, faster-to-change, more-flexible software? Almost, but not quite.

Rather, I feel that it’s because I want to preserve *meaning* in software, because that is the only thing of value. And I define meaning as relationships defined within a context. For a function, the meaning is the relationship between input and output, and the context is the type of the function.

Only by preserving “meaning” have we preserved the specification of the program, in a fine-enough grain to be reusable.

Haskell seems to me to be the language that best enables writing meanings of aspects of a program down in a concise, specification-oriented notation, in immutable rules about the system. Writing these meaning-relations as invariant-constraints (which I just called “immutable rules”) enables building systems that do not need to change radically when some small aspect of the environment changes.

This seems like a very important step for software to take, if we want to stop spinning our wheels in the IT world, reinventing the wheel thousands or millions of times, and move up the layers of abstraction toward truly flexible, and perhaps even slightly “intelligent” software.

Demos from StrangeLoop of live-programming environments seem quite relevant to this process of implementing abstractions in a functional-programming-language such as Haskell, because such demos seem like they would be in some cases almost trivial to implement with a model such as FRP. (A possible example is https://www.youtube.com/watch?v=i3Xack9ufYk  … but the video about Eve by Chris Granger may be a better example.)

 

 

 

Fixing MDX using F#

Something like this could be useful if you have a large MDX script and want to translate some codes from one set to another set. (Perhaps I should find a more compact representation for the code translation table, like JSON, or even just a delimited string. I miss Perl’s quoting and literal syntaxes, sometimes…)

A script I just wrote; slight changes to the “pat” to make it less specific to the cube I’m working on. Edit as necessary.

open System
open System.IO
open System.Text.RegularExpressions
let filename = @"c:\temp\mdxscript.txt"
let txt = File.ReadAllText filename

let pat = "(\[yourDimensionName\]\.\[yourHierarchyName\]\.&\[)(\d+)(\])"
let oldToSnomed = 
    Map.ofList
      [ "oldcode1", "snowmedcode1";
        "oldcode2", "snowmedcode2"]
let replacer (m:Match) = 
    let orig   = m.Captures.[0].Value 
    let before = m.Groups.[1].Value
    let code   = m.Groups.[2].Value
    let after  = m.Groups.[3].Value
    printfn "%s" code
    let converted = oldToSnomed.TryFind(code)
    match converted with 
        | Some snomed -> before + snomed + after
        | _ -> orig

let evaluator = new MatchEvaluator(replacer)

let txt2 = Regex.Replace(txt, pat, evaluator)

txt2

File.WriteAllText(filename, txt2) // overwrites with translated codes

another simple list comprehension

— Naive (and slow: 1.4 seconds) solution to:
http://bartoszmilewski.com/2015/05/14/using-monads-in-c-to-solve-constraints-2-the-state-monad/

-- Sendmoremoney.hs
import Data.List(nub)
import Text.Printf(printf)
 
printer :: Int -> Int -> Int -> Int
    -> Int -> Int -> Int -> Int
    -> Int -> Int -> Int -> Int -> Int
    -> String

printer = printf "%d%d%d%d + %d%d%d%d = %d%d%d%d%d"

main = mapM_ putStrLn $
  [ printer s e n d m o r e m o n e y |
    d <- [0..9] ,
    e <- [0..9] ,
    m <- [1..9] ,
    n <- [0..9] ,
    o <- [0..9] ,
    r <- [0..9] ,
    s <- [1..9] ,
    y <- [0..9] ,
    s*1000+e*100+n*10+d
    + m*1000+o*100+r*10+e
    == m*10000 + o*1000+n*100+e*10+y
    , ( length $ nub [d,e,m,n,o,r,s,y ] ) == 8
  ]
 

— PS C:\dev\hask> Measure-Command { .\sendmoremoney.exe }  | select TotalSeconds | Format-List

— TotalSeconds : 1.3789969

Formula Caching and Query Scope

Chris Webb's BI Blog

The Analysis Services formula engine’s ability to cache the results of calculated members can be crucial to the overall performance of your cube, but it’s all too easy to turn off this caching. I’ve blogged already about the impact that subselects have on this and today I thought I’d discuss how you need to be careful using different calculation contexts. This is a topic that’s covered in the Analysis Services 2008 Performance Guide, but I thought it would be worth talking about here because it does deserve a lot more visibility as an important cause of poor query performance, especially in SSRS reports with hand-coded MDX.

As you know, you can define calculated members in three different places in Analysis Services: on the cube (the global context), within the session (the session context) and in the WITH clause of a query (the query context). The important paragraph from the…

View original post 513 more words

MDX SCOPE subcube assignments

Aaron's MSBI / SQL / Functional-programming space

For weeks I’ve been fiddling with MDX SCOPE statements and not fully understanding them. I read they are “subcube assignments”, and initially took that literally, thinking the assignment was creating physically persisted calculations in the SSAS database. But I came to realize this assignment is virtual. This statement says it well:

SSAS 2008 SCOPE

“When working with the [Measures].[Staffing %] measure and we are calculating it for the last fortnight, its value is equal to the fortnight previous to it times 1.05.”

More generally, when the members of the current tuple for the current cell are the same as the members specified by the collection of SCOPE statements before the THIS=x*y assignment, perform that calculation. Otherwise return NULL, or an aggregated value if built.

Also, it seems a CALCULATE statement can be nested inside a SCOPE statement to force aggregations within that SCOPE. I might have to try that, and…

View original post 65 more words