Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Common Lisp provides many flexible coding options for achieving a given result. However, it is sometimes difficult to choose the best approach. For example, the following vector expressions all produce the same result in different ways.
(defparameter objects (list 1 2 3))
(apply #'vector objects)
(coerce objects 'vector)
(make-array (length objects) :initial-contents objects)
(read-from-string (format nil "#~S" objects))
Of course, some expressions are more flexible than others, depending on the required output; but for a given output as above, what criteria are useful for deciding which to use?
(apply #'vector objects) is subject to the usual limitations of APPLY, which is that objects shouldn't hold more than CALL-ARGUMENTS-LIMIT elements. This is bad style even when you have only a few arguments.
COERCE is great: not only it performs the job, it also conveys the intent very well. However, you won't be able to give additional parameters for the resulting vector (e.g. fill-pointer, etc.); you cannot convert nested lists into matrices.
MAKE-ARRAY gives you full control over the resulting array: adjustability, fill-pointer, dimensions, element-type, displacement.
READ-FROM-STRING is a big no for data conversion, in general. In terms of useless computations, this approach is the Rube Goldberg's version of coerce. It also comes with a lot of security concerns, unless you are 100% sure about what the string contains. Here, you create the string yourself, but if your data contains any value for which another part of the code redefined PRINT-OBJECT, the code might break.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I am learning the Julia language and would like to know which implementation is likely to have better performance.
In answer to question How to check if a string is numeric Julia last answer is
isintstring(str) = all(isdigit(c) for c in str)
This code works well, but it could be rewritten
isintstring = str -> mapreduce(isnumeric, &, collect(str))
Is the rewrite better or worse? or just different? The Julia Style Guide does not seem to provide guidance.
Edit: As originally expressed, this question was blocked for seeking opinion not facts. I have rephrased it in gratitude for the three outstanding and helpful answers the original question received.
If you are using collect there is probably something wrong with your code, especially if it's a reduction. So your second method needlessly allocates, and, furthermore, it does not bail out early, so it will keep going to the end of the string, even if the first character fails the test.
If you benchmark the performance, you will also find that mapreduce(isnumeric, &, collect(str)) is an order of magnitude slower, and that is without considering early bailout.
In general: Don't use collect(!), and bail out early if you can.
The idiomatic solution in this case is
all(isdigit, str)
Edit: Here are some benchmarks:
jl> using BenchmarkTools, Random
jl> str1 = randstring('0':'9', 100)
"7588022864395669501639871395935665186290847293742941917566300220720077480508740079115268449616551087"
jl> str2 = randstring('a':'z', 100)
"xnmiemobkalwiiamiiynzxxosqoavwgqbnxhzaazouzbfgfbiodsmhxonwkeyhxmysyfojpdjtepbzqngmfarhqzasppdmvatjsz"
jl> #btime mapreduce(isnumeric, &, collect($str1))
702.797 ns (1 allocation: 496 bytes)
true
jl> #btime all(isdigit, $str1)
82.035 ns (0 allocations: 0 bytes)
true
jl> #btime mapreduce(isnumeric, &, collect($str2))
702.222 ns (1 allocation: 496 bytes) # processes the whole string
false
jl> #btime all(isdigit, $str2)
3.500 ns (0 allocations: 0 bytes) # bails out early
false
The rewrite is definitely worse. Slower, less elegant and more verbose.
Another edit: I only noticed now that you are using isnumeric with mapreduce, but isdigit with all. isnumeric is more general and much slower than isdigit so that also makes a big difference. If you use isdigit instead, and remove collect, the speed difference isn't so big for numeric strings, but it still does not bail out early for non-numeric strings, so the best solution is still clearly all(isdigit, str).
Part of your question is about named vs anonymous functions. In the first case, you created a function via its first method and assigned it to an implicitly const variable isintstring. The function object itself also gets the name isintstring, as you can see in its type. You can't reassign the variable isintstring:
julia> isintstring(str) = all(isdigit(c) for c in str)
isintstring (generic function with 1 method)
julia> typeof(isintstring)
typeof(isintstring)
julia> isintstring = str -> mapreduce(isnumeric, &, collect(str))
ERROR: invalid redefinition of constant isintstring
julia> isintstring = 1
ERROR: invalid redefinition of constant isintstring
Now let's restart the REPL and switch the order to start at the second case. The second case creates an anonymous function, then assigns it to a variable isintstring. The anonymous function gets a generated name that can't be a variable. You can reassign isintstring as long as you're not trying to declare it const, which includes method definitions.
julia> isintstring = str -> mapreduce(isnumeric, &, collect(str))
#5 (generic function with 1 method)
julia> typeof(isintstring)
var"#5#6"
julia> isintstring(str) = all(isdigit(c) for c in str)
ERROR: cannot define function isintstring; it already has a value
julia> isintstring = 1
1
It's far more readable to add methods to a named function, all you have to do is define another method using the const name, like isintstring(int, str) = blahblah().
It's actually possible to add methods to an anonymous function, but you have to do something like this: (::typeof(isintstring))(int, str) = blahblah(). The variable isintstring may not always exist, and the anonymous function can have other references such as func_array[3], in which case you'll have to write (::typeof(func_array[3]))(int, str) = blahblah(). I think you'll agree that a const name is far clearer.
Anonymous functions tend to be written as arguments in method calls like filter(x -> x%3==0, A) where the anonymous function only needs 1 method. In such a case, creating a const-named function would only bloat the function namespace and force a reader to jump around the code. In fact, do-blocks exist to allow people to write a multiple-line anonymous function as a first argument without bloating the method call.
Just like Gandhi said "My life is my message", Julia says "My code is my guide". Julia makes it very easy to inspect and explore standard and external library code, with #less, #edit, methods, etc. Guides for semantic style are rather hard to pin down (as opposed to those for syntactic style), and Python is rather the exception than the rule when it comes to the amount of documentation and emphasis surrounding this. However, reading through existing widely used code is a good way to get a feel for what the common style is.
Also, the Julialang Discourse is a more useful resource than search engines seem to give it credit for.
Now, for the question in your title, "using functional idioms" is a broad and vague descriptor - Julian style doesn't generally place high emphasis on avoiding mutations (except for performance reasons), for eg., and side effects aren't something rare and smelly. Higher order functions are pretty common, though explicit map/reduce are only one part of the arsenal of tools that includes broadcasting, generators, comprehensions, functions that implicitly do the mapping for you (sum(f, A::AbstractArray; dims): "Sum the results of calling function f on each element of an array over the given dimensions"), etc.
There's also another factor to consider: performance trumps (almost) anything else. As the other answers have hinted at, which style you go for can be a matter of optimizing for performance. Code that starts out reading functional can have parts of it start mutating its inputs, parts of it become for loops, etc., as and when necessary for performance. So it's not uncommon to see a mixture of these different style in the same package or even the same file.
they are the same. and if you just look at it...clearly the first one is cleaner even shorter
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I need to find functions F and F_Verification such that:
F(Input1, RandomSeed1) = Output1
F(Input1, RandomSeed2) = Output2
F_Verification (Output1, Output2) = TRUE
Cryptographic requirements:
Given Output1 and Output2, you must not be able to find input.
F may be a surjective function yielding the same output ~1/Billion~ times. It would be best to have some flexibility in how often it is surjective.
F_Verification May yeild a false positive again ~1/Billion~ times with some flexibility
Extra Details
1. All Inputs will be unique
F_Verification must be a quick function
Ideally F is a slow function
Any suggestions on starting places would be much appreciated.
Thank you.
In general, you're going to have a hard time finding a function that does this, because the output of most cryptographic functions is designed to be indistinguishable from random. Therefore, it's unlikely that you're going to find a function that both produces two identical outputs based on a random seed and lets you recover any information about the input value without knowing the seed.
However, there are some constructions that you can use. If the two outputs can be the exact same output, then you can just skip the random seed and let F be a secure hash function, like SHA-256 or BLAKE2b. Then the verification is an equality comparison. This is the ideal situation that hash functions are designed for, and it's what I recommend unless you know you need different behavior.
If you need to have two different outputs, you can make F this:
F(input, seed) = SHA-256(input) || HMAC-SHA-256(seed, input)
This still reveals that your objects are the same, but it provides different output on a different seed. The verification is an equality comparison of the first 32 bytes.
Beyond that, you're looking at situations where your verification isn't cheap. You can use RSA-PSS to sign the objects, and the salt you use in the signature will make the two signatures different even if the input (which you will have then hashed) is the same. But RSA verification isn't super cheap as far as cryptographic functions go, although there are worse options.
Pretty much all the other operations involve knowing the seed in order to compare, and you haven't provided that as an option. If it is, you could use a 256-bit seed and make F into this:
F(input, seed) = AES-Key-Wrap(seed, SHA-256(input))
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Expression: z=a+b * b-(36/(b * b)/(1+(25/(b * b)))
I have no idea what data directives I should use and in what order I should write the code.
C = A + B for Z80 CPU:
ld a,A
ld b,B
add a,b ; a = C
C = A * B for 68000 CPU:
MOVE.W D0,A
MOVE.W D1,B
MULS.W D1,D0 ; D0 = C
et cetera ... check your target CPU instruction guide to see what arithmetic operations it does implement directly, and what operand types can be used for them, which registers you have available, and their data type...
Looks like you don't have to write universal math expression parser (this gets tricky quite quickly, once at high-school we had on programming competition the task to write exactly that, and at first we were like "what, a single task for 5h time, I will be done in 30min" ... then after 5h nobody's code passed the full test suite, best were around 80% correct).
So if only this particular expression should be calculated, you can "parse" it by hand, simplifying it down into particular steps involving only single operation and one of intermediate sub-results. Then just write that with your instructions, step by step, like you would calculate that by hand (also make sure you conform to the math expression calculation rules, you know which operations have priority over others? Parentheses override anything, then mul/div first, add/sub later, from left to right, but this is base school math stuff, so unless you are 10y.o., you shouldn't ask this).
If your CPU does not have instruction for division or multiplication, simply implement it by subtraction/addition in loop. It's very lame performance wise, but if you have to ask this question, then one can not expect you would even comprehend more advanced algorithm for these.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Is it possible to automatically generate a program/function by writing a certain amount of examples which show the before and after? How many examples would be needed to insure correctness and lack of holes? What is the name of doing such an automatic process?
It's called program synthesis or perhaps guessing. Your question reminds me of the 2013 ICFP programming contest where you were supposed to guess programs and all you had was the output for your chosen test input in a very simple functional language.
So imagine you wanted to make the identity function:
(define-by-example identity
(0 -> 0)
(1 -> 1))
There is something missing? What if I told you to make a function that returns it's own value for 0 and 1 only? How would you make that different than the above example? What if it's a non linear transformation. Eg. how many examples does it take to get a polynomial correct?
I guess we're back to something like this:
(define-by-example fib
(0 -> 0)
(1 -> 1)
(n -> (+ (fib (- n 1)) (fib (- n 2)))))
But many languages has exactly this. Even Schemes dirty cousin Racket has this:
#!racket
(define (fib n)
(match n
[0 0]
[1 1]
[n (+ (fib (- n 1)) (fib (- n 2)))]))
This is the Hello World of Haskell so we better write that next :-)
-- haskell
fib 0 = 0
fib 1 = 1
fib n = fib(n - 1) + fib(n - 2)
Now there are smart people out there that tries to find the best method of transferring the idea down to a syntax that is clear for the computer and us. I'm sure the essence of "by example" is good but it needs to be a way of explaining the corrolations too and I cannot think of a better way to do that than maths or code where maths don't apply.
This is a subdomain of machine learning called supervised learning. The most popular method to solve these problems is by using neural networks. Another method is genetic programming.
In the general case it is not possible to guarantee correctness, no matter how large the training set (number of examples) is. But in a typical application this is not required. The training is considered successfull if a high enough percentage os the results is correct.
Is it possible to automatically generate a program/function by writing a certain amount of examples which show the before and after?
I'd say yes, but ...
... it's not exactly that easy, and certainly not that generally applicable. There are basically two "approaches" that I know of:
a) Try to generate a program
Just pack together program code (most probably instructions from some instruction set) until you get the desired results. This can be done with brute force, but it's hardly possible to synthesize non-trivial functions, yet alone complete programs, or probably with techniques from your favorite artificial intelligence tool set, like hill climbing, simulated annealing, genetic programming and the whole rest.
The only reference that I know of is the "Superoptimizer" by Henry Massalin, which tries to generate a function that computes the same as a given function, just with fewer instructions.
It's probably better to use some higher level representation of "computation" than assembler instructions (probably the Lisp AST?), but that's just my guess.
b) Write a meta program that "somehow" learns to behave like the desired program
This is actually very common nowadays in the form of neural networks, e.g. for image or voice recognition. Here you don't try to get a program that does what you want (e.g. "recognize birds in arbitrary images") but rather write a general program that is capable of learning to "behave differently" and train that in order to behave as you want.
Note that there's a lot of effort going into understanding what these meta programs actually do after they learned their intended function. Just taking the first relevant result from a Google search is already an interesting read.
This question already has answers here:
How does one reduce a list of boolean values in Common Lisp?
(3 answers)
Closed 8 years ago.
I'm new to Common Lisp, so this got me a bit stumped and Google has failed me.
I have a function sizzle defined like
(defun sizzle (f &rest r) ...blah blah...)
And now I just need to check if all optional arguments are non-nil, so naturally I did
(apply #'and r)
...and then it turns out that and isn't a function, it's a macro (which I haven't got around to just yet).
So, my question is, is there a way to use macros as functions (much like above), or should I just make my own function to check if all values is a given list are non-nil? Or is there yet another approach I haven't thought of?
You can't use macros as functions (that's why it's better to make some things functions, and that's why compiler macros instead of regular macros are used for optimization).
I would use (every #'identity r) or (notany #'null r) instead of writing my own AND function for your example.