F# Interactive 옵션

F# Interactive 옵션

F# Interactive(dotnet fsi, 옛 이름은 fsi.exe)은 F# 코드를 한 줄 한 줄 실행하면서 바로 결과를 확인할 수 있는 대화형 도구예요. 이 글에서는 F# Interactive가 받아들이는 명령줄 옵션을 정리해 드릴게요. F# Interactive는 F# 컴파일러와 많은 옵션을 공유하면서도, 몇 가지 추가 옵션을 더 지원합니다.

출처: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options

본문

스크립팅에 F# Interactive 사용하기

F# Interactive(dotnet fsi)는 대화형(interactive)으로 실행할 수도 있고, 스크립트를 돌리기 위해 명령줄에서 실행할 수도 있어요. 명령줄에서 쓰는 문법은 다음과 같습니다.

dotnet fsi [options] [ script-file [arguments] ]

F# 스크립트 파일의 확장자는 .fsx예요.

F# Interactive 옵션 표

다음 표는 F# Interactive가 지원하는 옵션을 정리한 내용입니다. 이 옵션들은 명령줄에서 설정할 수도 있고, Visual Studio IDE에서도 설정할 수 있어요. IDE에서 설정하려면 도구(Tools) 메뉴 → 옵션(Options)F# Tools 노드 확장 → F# Interactive 순서로 들어가면 됩니다.

F# Interactive 옵션의 인자에 목록(list)이 들어가는 경우, 각 요소는 세미콜론(;)으로 구분해요.

옵션 설명
-- F# Interactive가 남은 인자들을 F# 프로그램이나 스크립트에 전달되는 명령줄 인자로 취급하도록 지시해요. 코드에서는 fsi.CommandLineArgs 목록으로 접근할 수 있습니다.
--checked[+|-] fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--checknulls[+|-] fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--codepage:<int> fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--consolecolors[+|-] 경고와 오류 메시지를 색상으로 출력해요.
--compilertool:<extensionsfolder> 디자인 타임 도구(design-time tool)를 담고 있는 어셈블리나 디렉터리를 참조해요. (짧은 형식: -t)
--crossoptimize[+|-] 모듈 간 최적화(cross-module optimization)를 켜거나 꺼요.
--debug[+|-] --debug:[full|pdbonly|portable|embedded] -g[+|-] -g:[full|pdbonly|portable|embedded] fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--define:<string> fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--deterministic[+|-] 결정적(재현 가능한) 어셈블리를 생성해요. 여기에는 모듈 버전 GUID와 타임스탬프도 포함됩니다.
--exec 명령줄에 주어진 파일을 불러오거나 스크립트 파일을 실행한 뒤 F# Interactive를 종료하라고 지시해요.
--fullpaths fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--gui[+|-] Windows Forms 이벤트 루프(Windows Forms event loop)를 켜거나 꺼요. 기본값은 켜져 있음(enabled)이에요.
--help -? 명령줄 문법과 각 옵션에 대한 간단한 설명을 화면에 표시해요.
--lib:<folder-list> -I:<folder-list> fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--load:<filename> 시작할 때 주어진 소스 코드를 컴파일하고, 컴파일된 F# 구조를 세션에 불러와요.
--mlcompatibility fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--noframework fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--nologo fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--nowarn:<warning-list> fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--optimize[+|-] fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--preferreduilang:<lang> 출력 언어 문화권(preferred UI language culture) 이름을 지정해요. 예를 들어 es-ES, ja-JP 같은 값이 들어갑니다.
--quiet F# Interactive가 stdout 스트림으로 출력하는 내용을 생략해요.
--quotations-debug F# 인용(quotation) 리터럴과 반영(reflected) 정의에서 파생된 식에 대해 추가 디버깅 정보를 내보내도록 지정해요. 디버깅 정보는 F# 식 트리 노드의 사용자 지정 특성(custom attributes)에 추가됩니다. 자세한 내용은 코드 인용(Code Quotations)Expr.CustomAttributes를 참고해 주세요.
--readline[+|-] 대화형 모드에서 탭 완성(tab completion)을 켜거나 꺼요.
--reference:<filename> -r:<filename> fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--tailcalls[+|-] tail IL 명령어의 사용을 켜거나 꺼요. 이 명령어는 꼬리 재귀(tail recursive) 함수를 위해 스택 프레임을 재사용하게 해 줍니다. 이 옵션은 기본적으로 켜져 있어요.
--targetprofile:<string> 이 어셈블리의 대상 프레임워크 프로필(target framework profile)을 지정해요. 유효한 값은 mscorlib, netcore, netstandard이고, 기본값은 mscorlib예요.
--use:<filename> 인터프리터가 시작할 때 주어진 파일을 초기 입력으로 사용하라고 지시해요.
--utf8output fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--warn:<warning-level> fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--warnaserror[+|-] fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.
--warnaserror[+|-]:<int-list> fsc.exe 컴파일러 옵션과 같아요. 자세한 내용은 컴파일러 옵션을 참고해 주세요.

F# Interactive 구조적 출력 (structured printing)

F# Interactive(dotnet fsi)는 값을 보고(report)할 때 확장된 버전의 구조적 일반 텍스트 형식(structured plain text formatting)을 사용해요.

  • %A 일반 텍스트 형식의 모든 기능을 지원하고, 일부 기능은 추가로 사용자 지정(customizable)할 수 있어요.
  • 출력 콘솔이 색상을 지원하면 출력에 색상이 적용됩니다.
  • 명시적으로 그 문자열을 평가(evaluate)하지 않는 한, 표시되는 문자열의 길이에 제한이 있어요.
  • fsi 객체를 통해 일련의 사용자 정의 가능한 설정을 제공해요.

보고된 값의 일반 텍스트 출력을 사용자 지정할 수 있는 설정은 다음과 같습니다.

open System.Globalization

fsi.FormatProvider <- CultureInfo("de-DE")  // control the default culture for primitives

fsi.PrintWidth <- 120        // Control the width used for structured printing

fsi.PrintDepth <- 10         // Control the maximum depth of nested printing

fsi.PrintLength <- 10        // Control the length of lists and arrays

fsi.PrintSize <- 100         // Control the maximum overall object count

fsi.ShowProperties <- false  // Control whether properties of .NET objects are shown by default

fsi.ShowIEnumerable <- false // Control whether sequence values are expanded by default

fsi.ShowDeclarationValues <- false // Control whether values are shown for declaration outputs

AddPrinterAddPrintTransformer로 사용자 지정하기

F# Interactive의 출력은 fsi.AddPrinterfsi.AddPrintTransformer를 사용해 사용자 지정할 수 있어요. 첫 번째 함수는 객체의 출력을 대체할 텍스트를 주고, 두 번째 함수는 대신 표시할 대리(surrogate) 객체를 반환합니다. 예를 들어 다음 F# 코드를 볼게요.

open System

fsi.AddPrinter<DateTime>(fun dt -> dt.ToString("s"))

type DateAndLabel =
    { Date: DateTime
      Label: string  }

let newYearsDay1999 =
    { Date = DateTime(1999, 1, 1)
      Label = "New Year" }

이 예제를 F# Interactive에서 실행하면 설정된 형식 옵션에 따라 출력됩니다. 이 경우에는 날짜와 시간의 형식에 영향을 주는 것을 확인할 수 있어요.

type DateAndLabel =
  { Date: DateTime
    Label: string }
val newYearsDay1999 : DateAndLabel = { Date = 1999-01-01T00:00:00
                                       Label = "New Year" }

fsi.AddPrintTransformer는 출력을 위한 대리 객체를 제공하는 데 사용할 수 있어요.

type MyList(values: int list) =
    member _.Values = values

fsi.AddPrintTransformer(fun (x:MyList) -> box x.Values)

let x = MyList([1..10])

이 코드는 다음과 같이 출력됩니다.

val x : MyList = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

fsi.AddPrintTransformer에 전달한 변환(transformer) 함수가 null을 반환하면, 해당 프린트 변환기는 무시돼요. 이 특성을 이용하면 obj 타입에서 시작해 어떤 입력 값이든 걸러낼(filter) 수 있습니다. 예를 들면 다음과 같아요.

fsi.AddPrintTransformer(fun (x:obj) ->
    match x with
    | :? string as s when s = "beep" -> box ["quack"; "quack"; "quack"]
    | _ -> null)

let y = "beep"

이 코드의 출력은 다음과 같습니다.

val y : string = ["quack"; "quack"; "quack"]

더 알아보기 (Learn more)

항목 설명
컴파일러 옵션 F# 컴파일러(fsc.exe)에서 사용할 수 있는 명령줄 옵션을 설명해요.