Ocaml equivalent for Lisp's let*? - lisp

I'd rather use let ... and ... and ... in than nested let's when possible, but the normal let syntax doesn't allow this for expressions that depend on each other.
Not allowed:
let encrypt password =
let seed = int 16
and keys = xlat seed (length password)
and plaintext = map code (explode password) in
map2 logxor plaintext keys
Does OCaml have an equivalent to Lisp's let*, which does allow this?

Nested let's don't need nested indentation, so that's good enough.

Related

what is the usage of getOrElse in scala

I'd like to get values from map like that
user_TopicResponses.put(
"3"+"_"+topicid,
Access.useradVectorMap.getOrElse(
"3"+"_"+topicid,
Access.useradVectorMap.getOrElse("3"+"_"+"0"),
Array(0.0)
)
)
What means if key in map value will be get, of else key is set to "3+"0" and value will also be get.
but it will be reported that:
too many arguments for method getOrElse: (key: String, default: => B1)B
You mixed up parentheses a bit :
Access.useradVectorMap.getOrElse("3"+"_"+"0"),Array(0.0) shoud in fact be
Access.useradVectorMap.getOrElse("3"+"_"+"0",Array(0.0))
It should be ok after that !
First off, I would suggest, at least for debugging purposes, to break your one statement into multiple statements. Your problem stems from a missing/misplaced parentheses. This would be much easier to see if you split your code up.
Secondly, it's good practice to use a variable or function for any repeated code, it makes it far easier to change and maintain (I like to use them for any hard coded value that might change later as well).
In order to only calculate the secondaryValue only if the primaryValue.getOrElse(...) goes to the "else" value, you can use a lazy val, which only evaluates if needed:
val primaryKey = "3_" + topicid
val secondaryKey = "3_0"
val secondaryDefaultValue = Array(0.0)
lazy val secondaryValue = Access.useradVectorMap.getOrElse(secondaryKey, secondaryDefaultValue )
val primaryValue = Access.useradVectorMap.getOrElse(primaryKey, secondaryValue)
user_TopicResponses.put(primaryKey, primaryValue)
This code is far easier to read and, more importantly, far easier to debug

In Kotlin, I can override some existing operators but what about creating new operators?

In Kotlin, I see I can override some operators, such as + by function plus(), and * by function times() ... but for some things like Sets, the preferred (set theory) symbols/operators don't exist. For example A∩B for intersection and A∪B for union.
I can't seem to define my own operators, there is no clear syntax to say what symbol to use for an operator. For example if I want to make a function for $$ as an operator:
operator fun String.$$(other: String) = "$this !!whatever!! $other"
// or even
operator fun String.whatever(other: String) = "$this !!whatever!! $other" // how do I say this is the $$ symbol?!?
I get the same error for both:
Error:(y, x) Kotlin: 'operator' modifier is inapplicable on this function: illegal function name
What are the rules for what operators can be created or overridden?
Note: this question is intentionally written and answered by the author (Self-Answered Questions), so that the idiomatic answers to commonly asked Kotlin topics are present in SO.
Kotlin only allows a very specific set of operators to be overridden and you cannot change the list of available operators.
You should take care when overriding operators that you try to stay in the spirit of the original operator, or of other common uses of the mathematical symbol. But sometime the typical symbol isn't available. For example set Union ∪ can easily treated as + because conceptually it makes sense and that is a built-in operator Set<T>.plus() already provided by Kotlin, or you could get creative and use an infix function for this case:
// already provided by Kotlin:
// operator fun <T> Set<T>.plus(elements: Iterable<T>): Set<T>
// and now add my new one, lower case 'u' is pretty similar to math symbol ∪
infix fun <T> Set<T>.u(elements: Set<T>): Set<T> = this.plus(elements)
// and therefore use any of...
val union1 = setOf(1,2,5) u setOf(3,6)
val union2 = setOf(1,2,5) + setOf(3,6)
val union3 = setOf(1,2,5) plus setOf(3,6)
Or maybe it is more clear as:
infix fun <T> Set<T>.union(elements: Set<T>): Set<T> = this.plus(elements)
// and therefore
val union4 = setOf(1,2,5) union setOf(3,6)
And continuing with your list of Set operators, intersection is the symbol ∩ so assuming every programmer has a font where letter 'n' looks ∩ we could get away with:
infix fun <T> Set<T>.n(elements: Set<T>): Set<T> = this.intersect(elements)
// and therefore...
val intersect = setOf(1,3,5) n setOf(3,5)
or via operator overloading of * as:
operator fun <T> Set<T>.times(elements: Set<T>): Set<T> = this.intersect(elements)
// and therefore...
val intersect = setOf(1,3,5) * setOf(3,5)
Although you can already use the existing standard library infix function intersect() as:
val intersect = setOf(1,3,5) intersect setOf(3,5)
In cases where you are inventing something new you need to pick the closest operator or function name. For example negating a Set of enums, maybe use - operator (unaryMinus()) or the ! operator (not()):
enum class Things {
ONE, TWO, THREE, FOUR, FIVE
}
operator fun Set<Things>.unaryMinus() = Things.values().toSet().minus(this)
operator fun Set<Things>.not() = Things.values().toSet().minus(this)
// and therefore use any of...
val current = setOf(Things.THREE, Things.FIVE)
println(-current) // [ONE, TWO, FOUR]
println(-(-current)) // [THREE, FIVE]
println(!current) // [ONE, TWO, FOUR]
println(!!current) // [THREE, FIVE]
println(current.not()) // [ONE, TWO, FOUR]
println(current.not().not()) // [THREE, FIVE]
Be thoughtful since operator overloading can be very helpful, or it can lead to confusion and chaos. You have to decide what is best while maintaining code readability. Sometimes the operator is best if it fits the norm for that symbol, or an infix replacement that is similar to the original symbol, or using a descriptive word so that there is no chance of confusion.
Always check the Kotlin Stdlib API Reference because many operators you want might already be defined, or have equivalent extension functions.
One other thing...
And about your $$ operator, technically you can do that as:
infix fun String.`$$`(other: String) = "$this !!whatever!! $other"
But because you need to escape the name of the function, it will be ugly to call:
val text = "you should do" `$$` "you want"
That isn't truly operator overloading and only would work if it is a function that can me made infix.

How do I turn the Result type into something useful?

I wanted a list of numbers:
auto nums = iota(0, 5000);
Now nums is of type Result. It cannot be cast to int[], and it cannot be used as a drop-in replacement for int[].
It's not very clear from the docs how to actually use an iota as a range. Am I using the wrong function? What's the way to make a "range" in D?
iota, like many functions in Phobos, is lazy. Result is a promise to give you what you need when you need it but no value is actually computed yet. You can pass it to a foreach statement for example like so:
import std.range: iota;
foreach (i ; iota(0, 5000)) {
writeln(i);
}
You don't need it for a simple foreach though:
foreach (i ; 0..5000) {
writeln(i);
}
That aside, it is hopefully clear that iota is useful by itself. Being lazy also allows for costless chaining of transformations:
/* values are computed only once in writeln */
iota(5).map!(x => x*3).writeln;
// [0, 3, 6, 9, 12]
If you need a "real" list of values use array from std.array to delazify it:
int[] myArray = iota(0, 5000).array;
As a side note, be warned that the word range has a specific meaning in D that isn't "range of numbers" but describes a model of iterators much like generators in python. iota is a range (so an iterator) that produced a range (common meaning) of numbers.

How to write a function (or a macro) to create a Vec and a reference to it?

So I have something like this:
let v = vec![...];
let s = Data { vec: &v, ... };
Perhaps this is misguided, but the idea is that many data structures could share the same vector. But for the case where I don't want to share, it would be convenient to have something like this:
let (v, s) = make_data(...);
Apparently, unlike the first example, there is no way to connect the lifetime of v and s (correct me if I'm wrong). Anyway, I understand the borrow checker rejects this. So I end up doing:
let v = vec![];
let s = make_data(&v, ...);
Now, perhaps, I could make one of those work:
let (v, s) = make_data!(...);
let s = make_data!(v, ...);
let s = make_data!(...);
The problem here is that thse macros would expand to something like { let v = vec![]; ... } and v's destructor will be run in the end of this block, but what I really want is to have it expand to something like the first example.
Now, I can make this work:
make_data!(v, s, ...);
But it's odd. Is there any other way to solve this?
Rust allows you to define multiple variables with the same name in the same block.
let a = vec![...];
let a = Data { vec: &a, ... };
On the second line, the new a is not in scope yet, so you can still refer to the previous definition of a. However, on the following statements, you can no longer refer to the original a definition, since the second definition shadows the first one; nevertheless, the Vec remains alive until the end of the block, as usual.
You can take advantage of this in your macro by only taking a single identifier and using it for both the Vec and the slice.

Haskell HDBC Elegance in F#?

I'm struck by Haskell's terseness and elegance. But I work in a .Net house, so I use F# when I can get away with it--I may be the only one of hundreds across the country who uses it.
Does ADO.NET or F# offer something as terse and elegant as HDBC's executeMany? I'm making my way through Real World Haskell. In chapter 21 it offers this example:
ghci> conn <- connectSqlite3 "test1.db"
ghci> stmt <- prepare conn "INSERT INTO test VALUES (?, ?)"
ghci> executeMany stmt [[toSql 5, toSql "five's nice"], [toSql 6, SqlNull]]
ghci> commit conn
ghci> disconnect conn
I'd like to get this elegance and terseness in my F#. I've seen a lot of hype around using parameterized queries to avoid SQL injection attacks. I'm not using them in this case for three reasons:
I find parameterized queries in .Net ugly and burdensome.
My data comes from the corporate office, so it's (mostly) clean.
My table has 34 columns. I despise the idea of parameterizing a query with 34 columns.
Here's my F# code:
module Data
open System
open System.Data
open System.Data.OleDb
open System.Text.RegularExpressions
type Period = Prior | Current
let Import period records db =
use conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + db + ";Persist Security Info=False;")
let execNonQuery s =
let comm = new OleDbCommand(s, conn) in
comm.ExecuteNonQuery() |> ignore
let enquote = sprintf "\"%s\""
let escapeQuotes s = Regex.Replace(s, "\"", "\"\"")
let join (ss:string[]) = String.Join(",", ss)
let table = match period with
| Prior -> "tblPrior"
| Current -> "tblCurrent"
let statements =
[| for r in records do
let vs = r |> Array.map (escapeQuotes >> enquote) |> join
let vs' = vs + sprintf ",\"14\",#%s#" (DateTime.Now.ToString "yyyy-MM-dd") in
yield sprintf "INSERT INTO %s ( [Field01], [Field02], [Field03] [Field04], [Field05], [Field06], [Field07], [Field08], [Field09], [Field10], [Field11], [Field12], [Field13], [Field14], [Field15], [Field16], [Field17], [Field18], [Field19], [Field20], [Field21], [Field22], [Field23], [Field24], [Field25], [Field26], [Field27], [Field28], [Field29], [Field30], [Field31], [Field32], [Field33], [Field34] ) VALUES (%s)" table vs' |] in
do conn.Open()
execNonQuery (sprintf "DELETE FROM %s" table)
statements |> Array.iter execNonQuery
I've renamed the fields of the table(s) for security reasons.
Because all the fields on the table are text, I can easily Array.map them to escape and quote the values.
At between 9,000 and 10,000 records per day to import to each of the two tables, I want to do this as efficiently as possible. Hence my interest in the executeMany of Haskell. Too, though, I like the idea behind parameterized queries, and I like the way Hasekll has implemented them. Is there something equivalent in terseness and elegance in F#?
I agree with #JonnyBoats comment that generally using an F# SQL type provider like SqlDataConnection (LINQ-to-SQL) or SqlEntityConnection (Entity Framework) would be far more elegant than any kind of solution involving building insert statement strings by hand.
But, there is one important qualifier to your question: "At between 9,000 and 10,000 records per day to import to each of the two tables, I want to do this as efficiently as possible." In a scenario like this, you'll want to use SqlBulkCopy for efficient bulk inserts (it leverages native database driver features for much faster inserts than you are likely getting with HDBC's executeMany).
Here's a small example that should help you getting started using SqlBulkCopy with F#: https://stackoverflow.com/a/8942056/236255. Note that you'll be working with a DataTable to stage the data which though old and somewhat awkward to use from F#, is still superior to building insert statement strings in my opinion.
Update in response to comment
Here's a generalized approach to using SqlBulkCopy which is improved for your scenario (we pass in a column specification separately from the row data, and both are dynamic):
//you must reference System.Data and System.Xml
open System
open System.Data
open System.Data.SqlClient
let bulkLoad (conn:SqlConnection) tableName (columns:list<string * Type>) (rows: list<list<obj>>) =
use sbc = new SqlBulkCopy(conn, SqlBulkCopyOptions.TableLock, null, BatchSize=500, BulkCopyTimeout=1200, DestinationTableName=tableName)
sbc.WriteToServer(
let dt = new DataTable()
columns
|> List.iter (dt.Columns.Add>>ignore)
for row in rows do
let dr = dt.NewRow()
row |> Seq.iteri(fun i value -> dr.[i] <- value)
dt.Rows.Add(dr)
dt)
//example usage:
//note: since you know all your columns are of type string, you could define columns like
//let columns = ["Field1", "Field2", "Field3"] |> List.map (fun name -> name, typeof<String>)
let columns = [
"Field1", typeof<String>
"Field2", typeof<String>
"Field3", typeof<String>
]
let rows = [
["a"; "b"; "c"]
["d"; "e"; "f"]
["g"; "h"; "i"]
["j"; "k"; "l"]
["m"; "n"; "o"]
]
//a little funkiness to transform our list<list<string>> to list<list<obj>>,
//probably not needed in practice because you won't be constructing your lists literally
let rows = rows |> List.map (fun row -> row |> List.map (fun value -> value :> obj))
bulkLoad conn "tblPrior" columns rows
You could get even fancier / more terse using an approach involving reflection. e.g. create a type like
type RowData = { Field1:string; Field2:string; Field3:string }
and make a bulkLoad with a signature that takes a list<'a> argument such that it reflects over the property names and types of typeof<'a> to build the DataTable Columns, and similarly uses reflection to iterate over all the properties of a row instance to create and add a new row to the DataTable. In fact, this question shows how to make a generic ToDataTable method that does it (in C#).