dcli
  • Introduction
  • What does DCli do?
  • Install DCli
    • Installing on Windows
  • Writing your first CLI app
  • Add DCli to your project
  • pub.dev
  • github
  • Dart basics
    • Dart lambda functions
    • Function Arguments
    • Futures
    • stdin/stdout/stderr a primer
  • Tour
    • Overview
    • Using DCli functions
    • User input
      • Ask Validators
    • Displaying information
    • Managing Files And Directories
    • Environment variables
    • Calling apps
    • Redirecting output
    • Command Line Arguments
    • Paths
    • Glob Expansion
    • Piping
    • Locking
    • Fetch
    • The evils of CD
    • Assets/Resources
    • Cross Platform
      • Posix
      • Windows
      • Docker
        • Detecting Docker
        • Add DCli to a Docker Container
        • Example DCli app in Docker
  • Elevated Privileges
    • Sudo
  • Performance
  • Dependency Management
    • Dependency Management
    • Pubspec Managment
  • DCli Tools
    • DCli tools
    • Use a shebang #!
    • DCli Compile
    • DCli Clean
    • DCli Create
    • DCli Doctor
    • DCli Install
    • DCli Run
    • DCli Warmup
    • DCli Pack
    • Upgrade DCli
  • Internal Workings
    • Internal Workings
    • waitForEx
  • Contributing
    • Creating a release
    • Running Unit tests
    • Implemention support for a shell
    • Templates
  • References
  • Examples
    • Projects
    • Code
      • hello world.
      • dcompress
      • dpath
      • dmysql
      • dshell
      • dwhich
      • dipaddr
      • gnome launcher
  • Articles
    • build CLI apps in dart - part 1
    • build CLI apps in dart - part 2
    • Dealing with permissions
    • 3rd Party console packages
  • Dart on Linux - the perfect CLI tooling
  • Improving your build environment
    • Existing tooling
    • Building with Dart
    • A home for your build tools
  • Olivier Revial - CLI apps made easy
  • Video: package of the week
Powered by GitBook
On this page

Was this helpful?

  1. Dart basics

Dart lambda functions

PreviousgithubNextFunction Arguments

Last updated 1 year ago

Was this helpful?

This section provides details on the Dart language:

To learn more about Dart's syntax read the Dart language tour.

DCli makes extensive use of Dart's lambdas.

Lambdas are essentially anonymous functions which DCli uses for callbacks.

The most common use of lambdas in DCli are in the forEach method.

In prior examples you have already seen the forEach method in action.

'tail tmp/nonexistant.txt'.forEach((line) => print(line));

The signature of the forEach method is:

void forEach(LineAction stdout, {LineAction stderr});

The first argument stdout of the forEach method is a 'positional' argument, the second argument stderr is a named argument. The stdout argument is required whilst the stderr argument is optional.

LineAction is a Dart typedef that declares that LineAction is a function that takes a single String.

typedef LineAction = void Function(String line);

Essentially this means that forEach expects you to pass a function to the first positional argument stdout and optionally the second argument stderr.

The functions that you pass are unnamed or anonymous functions known as a Lambda.

The following code uses the [stdout] positional argument to print each line returned by the call to the Linux 'tail' command.

'tail tmp/nonexistant.txt'.forEach(
    (line) => print(line)
    );

The 2nd line is the Lambda function that you provide.

Lets break this down.

The line consists of three components

(line) => print(line)

Which can be abstracted to:

(<args>) => <expression>

In our example the stdout positional argument is of type LineAction. The LineAction function takes a String as its only argument. So in this case (<args>) is a single argument of type String.

What this means is that the forEach method will call the Lambda function each time the tail command outputs a line. The value of that line will be contained in the line argument passed to your Lambda.

The second component is the => operator, sometimes referred to as a 'fat arrow'. Essentially the => operator passes the line argument to the <expression>;

The third and final component is the <expression>.

The <expression> can be any valid Dart expression. In the above example the expression is print(line) which prints the contents of line to the console.

One limitation of the <expression> is that it must be a single line expression. Our LineAction is declared as returning a void so in our case the return value of the expression is ignored.

Dart's Lambdas actually take two forms; the above 'fat arrow' form and a 'block form'.

The block form allows you to execute multiple statements and requires you to use a return statement if you want to return something from the Lambda.

The syntax of the Lambda block form is:

(args) { <statements> }

Look carefully and note that the block form doesn't have the 'fat arrow'. I've often been caught when converting a 'fat arrow' form to the block form leaving the 'fat arrow' in place; that just doesn't work.

Block form example of a Lambda:

'tail tmp/nonexistant.txt'.forEach(
    (line) {
         String trimmed = line.trim();
         print(trimmed);

         // If LineAction took a non-void return type then we could use 
         // a return statement here
         // return 'some value';
    }
);

Have a look a the next section of named arguments to understand how to process stderr when interacting with the forEach method.

https://dart.dev/guides/language/language-tour