Tag Info

New answers tagged

0

My understanding is that a lazy evaluated language actually holds everything in a wrapper like this: class LogicalValue { ActualValue *value; ActualValue operator()() { if (value == null) { value = computeValue(); } return value; } } This is like your caching example, except that it doesn't attempt to reuse ...


1

After thinking about it overnight and looking at Nebu's answer, here are the solutions I came up with: Return only the URI, and accept one a/sync Func. While I do think it's reasonable for an API to return the URI to a video (in case the user doesn't want to download it just yet), I think it's a bit technical to ask him/her to download the source of the ...


1

Why not make FromYouTubeAsync be a pure function (e.g. which takes a String representing the HTML of the youtube video page, and which returns the URL of the mp4 video file it finds within), and then have the caller worry about how exactly to download bytes over the internet, if you think they want to have as much control over the process as you're implying? ...


2

Your first argument regarding reuse of the HttpClient makes perfect sense. As for the rest of of the requests, I think you're trying to optimize prematurely. That can lead to unnecessary complexity. Also, I'd like to warn you of using the static classes. This is usually a bad idea. It makes your code harder to test and extend. Anyways, below is a design that ...


5

Is there still any functional programming language that doesn't rely on C runtime? Yes, at least if you consider (like I do) that Lisp variants are functional languages (because they have the application and abstraction operators of the lambda-calculus), and that any language with closures and abstraction is functional: Bones is an implementation of ...


4

You seems to want to make some optimization (e.g. common subexpression extraction, as commented by rwong) in your interpreter. Notice also that a language (even a domain-specific language) is never defined by some internal representation, but a computer language is defined by its syntax and its semantics (so you'll better define them first, at least on ...


0

The real solution is not by collecting everything to a big World object, and then passing it around. Instead, you're recommended to accurately specify the type of the function you're dealing with. Here's some examples: BAD: f :: (World, Int) -> World Good: f :: (Int,Int,Int,Int) -> World The bad example is trying to modify existing object, ...


3

It may surprise you to learn that pattern matching is not considered the most idiomatic way to work with Options. See the documentation of Scala's Options for more about that. I'm not sure why so many FP tutorials encourage this usage. Mostly what you're missing is there are a whole bunch of functions created to make working with Options easier. Consider ...


11

So does functional programming just add a cleaner syntax that makes this style of programming seem less gross? That is a simplification perhaps, but yes. What else am I missing? Let's be clear on what algebraic data types are (summarizing this fine link from Learn you as Haskell): A sum type that says "this value can be an A or a B". A product ...


36

Classes with interfaces and inheritance present an open world: Anyone can add a new kind of data. For a given interface, there may be classes implementing it all over the world, in different files, in different projects, at different companies. They make it easy to add cases to the data structures, but because the implementations of the interface are ...


-4

A closure is a shorthand way of writing a method where it is to be used. It saves you the effort of declaring and writing a separate method. It is useful when the method will be used only once and the method definition is short. The benefits are reduced typing as there is no need to specify the name of the function, its return type or its access modifier. ...


-1

Pretty much all statically-typed functional languages have a way to alias basic types in a way that requires you to explicitly declare your semantic intent. Some of the other answers have given examples. In practice, experienced functional programmers need very good reasons to use those wrapper types, because they hurt composability and reusability. For ...


0

I disagree that a single function can't have a 'semantic contract'. Consider these laws for foldr: foldr f z nil = z foldr f z (singleton x) = f x z foldr f z (xn <> ys) = foldr f (foldr f z ys) xn In what sense is that not semantic, or not a contract? You don't need to define a type for a 'foldrer', especially because foldr is uniquely determined ...


15

First of all, there is nothing that is impossible without using closures. You can always replace a closure by an object implementing a specific interface. It's only a matter of brevity and reduced coupling. Second, keep in mind that closures are often used inappropriately, where a simple function reference or other construct would be more clear. You ...


9

When doing FP I tend to use more specific semantic types. For example, your method for me would become something like: read: MessageId -> Message This communicates quite a lot more than the OO(/java)-style ThingDoer.doThing() style


5

As Telastyn says, comparing the static definitions of functions: public string Read(int id) { /*...*/ } to let read (id:int) = //... You haven't really lost anything going from OOP to FP. However, this is only part of the story, because functions and interfaces aren't only referred to in their static definitions. They're also passed around. So let's ...


8

So, what can functional programmers do to preserve the semantics of a well-named interface? Use well named functions. IMessageQuery::Read: int -> string simply becomes ReadMessageQuery: int -> string or something similar. The key thing to note is that names are only contracts in the loosest sense of the word. They only work if you and another ...


16

Stacks allow us to elegantly bypass the limits imposed by the finite number of registers. Imagine having exactly 26 globals "registers a-z" (or even having only the 7 byte-sized registers of the 8080 chip) And every function you write in this app shares this flat list. A naive start would be to allocate the first few registers to the first function, and ...


6

Inlining (replacing function calls with equivalent functionality) works well as an optimization strategy for small simple functions. The overhead of a function call can be effectively traded off for a small penalty in added program size (or in some cases, no penalty at all). However, large functions which in turn call other functions could lead to an ...


11

Cases which that approach cannot handle: function fib(a) { if(a>2) return fib(a-1)+fib(a-2); else return 1; } function many(a) { for(i = 1 to a) { b(i); };} There are languages and platforms with limited or no call stacks. PIC microprocessors have a hardware stack limited to between 2 and 32 entries. This creates design constraints. COBOL bans ...


7

You want function inlining, and most (optimizing) compilers are doing that. Notice that inlining requires the called function to be known (and is effective only if that called function is not too big), since conceptually it is substituting the call by the rewriting of the called functgion. So you generally cannot inline an unknown function (e.g. a function ...


47

There are two parts to your question: Why have multiple functions at all (instead of replacing function calls with their definition) and why implement those functions with call stacks instead of statically allocating their data somewhere else? The first reason is recursion. Not just the "oh let's make a new function call for every single item in this list" ...


73

This is called "inlining" and many compilers do this as an optimization strategy in cases where it makes sense. In your particular example, this optimization would save both space and execution time. But if the function was called in multiple places in the program (not uncommon!), it would increase code size, so the strategy becomes more dubious. (And of ...


5

SQL is based on Relational Algebra and Tuple Relational Calculus, not higher-order functions or functional programming. While SELECT, FROM and WHERE have analogous functions in other languages, SQL itself doesn't support generalized higher order functions, but only those "higher-order" functions that the language itself defines. Since SQL doesn't allow ...


3

Have a look at LINQ, which takes the basic concepts behind SQL and generalizes it to object-oriented programming. The Where operator is a bog-standard Filter, the Select operator is a projection/Map, and so on. All of the basic SQL query operations are represented in LINQ, implemented using higher-order functions, so yes, you're correct in your intuitive ...


1

I will say that it's not limited to functional programming, it's more related to the goal of the project. By using predicate logic (higher order logic) you can create prove for the logic used in the requirement. Translating the logic into functional languages is probably easier. It's also possible to then translate the proven functional language ...


-1

That's one way to deal with functional programming. It tends to fall out from the flowcharts and data flow diagrams of the "old days." Instead of thinking in terms of objects, functional programming tends to focus on what actions need to be performed. The data becomes incidental, bits of fluff to carry along to hold on to what you're trying to do.


3

How can varargs be implemented? We need some mechanism to signal the end of the argument list. This can either be a special terminator value, or the length of the vararg list passed as an extra parameter. Both of these mechanisms can be used in the context of currying to implement varargs, but proper typing becomes a major issue. Let's assume that we are ...


1

Although jozefg provided an answer, I am not sure if it answered the question. The "fusion law" is explained in the following paper: A tutorial on the universality and expressiveness of fold, GRAHAM HUTTON, 1999 Basically it says that under some conditions you can combine ("fuse") the composition of a function and fold into a single fold, so ...


6

Nothing that hasn't been said already, but maybe a simpler example. Here's a JavaScript example using timeouts: // Example function that logs something to the browser's console after a given delay function delayedLog(message, delay) { // this function will be called when the timer runs out var fire = function () { console.log(message); // closure ...


3

PHP can be used to help to show a real example in a different language. protected function registerRoutes($dic) { $router = $dic['router']; $router->map(['GET','OPTIONS'],'/api/users',function($request,$response) use ($dic) { $controller = $dic['user_api_controller']; return $controller->findAllAction($request,$response); ...


13

A couple of other examples: Sorting Most sort functions operate by comparing pairs of objects. Some comparison technique is needed. Restricting the comparison to a specific operator means a rather inflexible sort. A much better approach is to receive a comparison function as an argument to the sort function. Sometimes a stateless comparison function works ...


7

Closures are equivalent to objects implementing a run() method, and inversely, objects can be emulated with closures. The advantage of closures is that they can be used easily anywhere you expect a function: a.k.a. higher-order functions, simple callbacks (or Strategy Pattern). You don't need to define an interface/class to build ad-hoc closures. The ...


19

The purpose of closures is simply to preserve state; hence the name closure - it closes over state. For the ease of further explanation, I'll use Javascript. Typically you have a function function sayHello(){ var txt="Hello"; return txt; } where the scope of the variable(s) is bound to this function. So after execution the variable txt goes out ...


45

By way of explanation, I'm going to borrow some code from this excellent blog post about closures. It's JavaScript, but that's the language most blog posts that talk about closures use, because closures are so important in JavaScript. Let's say you wanted to render an array as an HTML table. You could do it like this: function renderArrayAsHtmlTable ...


14

There are two main use cases for closures: Asynchrony. Let's say you want to perform a task that will take a while, and then do something when it's done. You can either make your code wait for it to be done, which blocks further execution and can make your program unresponsive, or call your task asynchronously and say "begin this long task in the ...



Top 50 recent answers are included