Default function parameters


#1

Given that a function has a type and given that we can define defaults for types, I’m curious if anyone tried to define default function [formal] parameters.


#2

…we can define defaults for types…

Precisely: We can define schemas for record types. It implies

  1. that the following solution works only if the function take a record parameter. (Either because it’s the function “natural” parameter, or because you choose to pass multiple arguments using the record trick)
  2. Default values and record types are connected through a schema, which is a record value. You can define as many schemas as you wanf for a given type.
let Breakfast = { eggs : Text, beans : Text }
let Breakfast/Schema = {
  , Type = Breakfast
  , default = { eggs : "spam", beans : "spam" }
  }

let order = \( br : Breakfast ) -> "${br.eggs} spam ${br.beans}"

-- Now the caller can use record completion.

let myOrder = assert : order Breakfast/Schema::{ beans = "baked" } === "spam spam backed"

Then you (sort-of) have default function parameters. Note that even if you don’t want to override any parameter you still have to complete the schema : order Breakfast/Schema::{=}

That’s when you control the definitions of Breakfast* and order. Sometimes you don’t, when they come from an imported package. There’s a (weak) convention (described here) to define things in packages like that:

let Breakfast = { eggs : Text, beans : Text }

let order
    : Breakfast -> Text
    = \( br : Breakfast )
      -> "${br.eggs} spam ${br.beans}"

let Breakfast = {  -- shadow the Breakfast Type with the  Breakfast Schema
  , Type = Breakfast
  , default = { eggs : "spam", beans : "spam" }
  }

in {
  , Breakfast
  , order
  }

This already enables the record completion trick ( order Breakfast::{ beans = "baked" }) for you, but nothing prevents you from defining your own defaults in your own schema:

let spam = https://circus.org/spam.dhall
let MyBreakfast = {
  , Type : spam.Breakfast.Type
  , default : spam.Breakfast::{ beans = "baked" }
  }
let myOrder = assert : spam.order MyBreakfast::{ eggs = "omelette" } === "omelette spam baked"

I hope that’s helpful. I understand that you want to provide defaults parameters to the users of your function. Just define a schema for the record that holds parameters.