[{"data":1,"prerenderedAt":5600},["ShallowReactive",2],{"navigation":3,"api-navigation":184,"\u002Flearn\u002Ftutorials\u002Ftyped-groups-and-schemas":206,"docyard:crossref-index":5599},[4,8,155,174,180],{"title":5,"path":6,"stem":7},"Getting Started","\u002Fgetting-started","1.getting-started",{"title":9,"path":10,"stem":11,"children":12},"Learn","\u002Flearn","2.learn",[13,15,66,99,133],{"title":9,"path":10,"stem":14},"2.learn\u002Findex",{"title":16,"path":17,"stem":18,"children":19},"Tutorials","\u002Flearn\u002Ftutorials","2.learn\u002F1.tutorials\u002Findex",[20,21,26,30,34,38,42,46,50,54,58,62],{"title":16,"path":17,"stem":18},{"title":22,"path":23,"stem":24,"icon":25},"Why Laco?","\u002Flearn\u002Ftutorials\u002Fwhy-laco","2.learn\u002F1.tutorials\u002F01.why-laco","i-lucide-notebook",{"title":27,"path":28,"stem":29,"icon":25},"First Steps with Laco","\u002Flearn\u002Ftutorials\u002Ffirst-steps","2.learn\u002F1.tutorials\u002F02.first-steps",{"title":31,"path":32,"stem":33,"icon":25},"Lazy Call and Partial","\u002Flearn\u002Ftutorials\u002Flazy-call-and-partial","2.learn\u002F1.tutorials\u002F03.lazy-call-and-partial",{"title":35,"path":36,"stem":37,"icon":25},"Hyperparameters and Interpolation","\u002Flearn\u002Ftutorials\u002Fhyperparameters-and-interpolation","2.learn\u002F1.tutorials\u002F04.hyperparameters-and-interpolation",{"title":39,"path":40,"stem":41,"icon":25},"Loading, Saving, and the CLI","\u002Flearn\u002Ftutorials\u002Floading-saving-cli","2.learn\u002F1.tutorials\u002F05.loading-saving-cli",{"title":43,"path":44,"stem":45,"icon":25},"Nested Configs and Containers","\u002Flearn\u002Ftutorials\u002Fnested-configs-and-containers","2.learn\u002F1.tutorials\u002F06.nested-configs-and-containers",{"title":47,"path":48,"stem":49,"icon":25},"Typed Groups and Schemas","\u002Flearn\u002Ftutorials\u002Ftyped-groups-and-schemas","2.learn\u002F1.tutorials\u002F07.typed-groups-and-schemas",{"title":51,"path":52,"stem":53,"icon":25},"Pipeline Configs","\u002Flearn\u002Ftutorials\u002Fpipeline-configs","2.learn\u002F1.tutorials\u002F08.pipeline-configs",{"title":55,"path":56,"stem":57,"icon":25},"Tasks and the App Loop","\u002Flearn\u002Ftutorials\u002Ftasks-and-app-loop","2.learn\u002F1.tutorials\u002F09.tasks-and-app-loop",{"title":59,"path":60,"stem":61,"icon":25},"Tracing","\u002Flearn\u002Ftutorials\u002Ftracing","2.learn\u002F1.tutorials\u002F10.tracing",{"title":63,"path":64,"stem":65,"icon":25},"Production Patterns","\u002Flearn\u002Ftutorials\u002Fproduction-patterns","2.learn\u002F1.tutorials\u002F11.production-patterns",{"title":67,"path":68,"stem":69,"children":70},"Concepts","\u002Flearn\u002Fconcepts","2.learn\u002F2.concepts\u002Findex",[71,72,76,80,84,88,92,95],{"title":67,"path":68,"stem":69},{"title":73,"path":74,"stem":75},"Config as Python","\u002Flearn\u002Fconcepts\u002Fconfig-as-python","2.learn\u002F2.concepts\u002F1.config-as-python",{"title":77,"path":78,"stem":79},"Lazy Construction","\u002Flearn\u002Fconcepts\u002Flazy-construction","2.learn\u002F2.concepts\u002F2.lazy-construction",{"title":81,"path":82,"stem":83},"Lie-Typing","\u002Flearn\u002Fconcepts\u002Flie-typing","2.learn\u002F2.concepts\u002F3.lie-typing",{"title":85,"path":86,"stem":87},"Interpolation","\u002Flearn\u002Fconcepts\u002Finterpolation","2.learn\u002F2.concepts\u002F4.interpolation",{"title":89,"path":90,"stem":91},"Typed Groups","\u002Flearn\u002Fconcepts\u002Ftyped-groups","2.learn\u002F2.concepts\u002F5.typed-groups",{"title":59,"path":93,"stem":94},"\u002Flearn\u002Fconcepts\u002Ftracing","2.learn\u002F2.concepts\u002F6.tracing",{"title":96,"path":97,"stem":98},"App Loop","\u002Flearn\u002Fconcepts\u002Fapp-loop","2.learn\u002F2.concepts\u002F7.app-loop",{"title":100,"path":101,"stem":102,"children":103},"How-To Guides","\u002Flearn\u002Fhow-to","2.learn\u002F3.how-to\u002Findex",[104,105,109,113,117,121,125,129],{"title":100,"path":101,"stem":102},{"title":106,"path":107,"stem":108},"Override Configs","\u002Flearn\u002Fhow-to\u002Foverride-configs","2.learn\u002F3.how-to\u002F1.override-configs",{"title":110,"path":111,"stem":112},"Safe Loading","\u002Flearn\u002Fhow-to\u002Fsafe-loading","2.learn\u002F3.how-to\u002F2.safe-loading",{"title":114,"path":115,"stem":116},"Custom Resolvers","\u002Flearn\u002Fhow-to\u002Fcustom-resolvers","2.learn\u002F3.how-to\u002F3.custom-resolvers",{"title":118,"path":119,"stem":120},"Lint and Strict Mode","\u002Flearn\u002Fhow-to\u002Flint-and-strict","2.learn\u002F3.how-to\u002F4.lint-and-strict",{"title":122,"path":123,"stem":124},"Publishing a reproducible app with laco app","\u002Flearn\u002Fhow-to\u002Flaco-app","2.learn\u002F3.how-to\u002F5.laco-app",{"title":126,"path":127,"stem":128},"Reproduce an Experiment","\u002Flearn\u002Fhow-to\u002Freproduce-experiment","2.learn\u002F3.how-to\u002F6.reproduce-experiment",{"title":130,"path":131,"stem":132},"Migrate from argparse","\u002Flearn\u002Fhow-to\u002Fmigrate-from-argparse","2.learn\u002F3.how-to\u002F7.migrate-from-argparse",{"title":134,"path":135,"stem":136,"children":137},"Examples Curriculum","\u002Flearn\u002Fexamples","2.learn\u002F4.examples\u002Findex",[138,139,143,147,151],{"title":134,"path":135,"stem":136},{"title":140,"path":141,"stem":142},"Foundation Examples","\u002Flearn\u002Fexamples\u002Ffoundations","2.learn\u002F4.examples\u002F1.foundations",{"title":144,"path":145,"stem":146},"Building Blocks","\u002Flearn\u002Fexamples\u002Fbuilding-blocks","2.learn\u002F4.examples\u002F2.building-blocks",{"title":148,"path":149,"stem":150},"Typed-Group Variants","\u002Flearn\u002Fexamples\u002Ftyped-variants","2.learn\u002F4.examples\u002F3.typed-variants",{"title":152,"path":153,"stem":154},"End-to-End Pipelines","\u002Flearn\u002Fexamples\u002Fpipelines","2.learn\u002F4.examples\u002F4.pipelines",{"title":156,"path":157,"stem":158,"children":159},"Resources","\u002Fresources","3.resources",[160,162,166,170],{"title":156,"path":157,"stem":161},"3.resources\u002Findex",{"title":163,"path":164,"stem":165},"Integrations","\u002Fresources\u002Fintegrations","3.resources\u002F1.integrations",{"title":167,"path":168,"stem":169},"Migration guide: Laco 0.x → 1.0","\u002Fresources\u002Fmigration-0.x-to-1.0","3.resources\u002F2.migration-0.x-to-1.0",{"title":171,"path":172,"stem":173},"Laco vs hydra-zen","\u002Fresources\u002Flaco-vs-hydra-zen","3.resources\u002F3.laco-vs-hydra-zen",{"title":175,"path":176,"stem":177,"children":178},"API Reference","\u002Fapi","4.api\u002Findex",[179],{"title":175,"path":176,"stem":177},{"title":181,"path":182,"stem":183},"Lazy Configuration for Python","\u002F","index",[185,188,191,194,197,200,203],{"title":186,"path":187},"cli","\u002Fapi\u002Fcli",{"title":189,"path":190},"compat","\u002Fapi\u002Fcompat",{"title":192,"path":193},"handler","\u002Fapi\u002Fhandler",{"title":195,"path":196},"keys","\u002Fapi\u002Fkeys",{"title":198,"path":199},"language","\u002Fapi\u002Flanguage",{"title":201,"path":202},"ops","\u002Fapi\u002Fops",{"title":204,"path":205},"utils","\u002Fapi\u002Futils",{"id":207,"title":47,"body":208,"description":5593,"extension":5594,"meta":5595,"navigation":5596,"path":48,"seo":5597,"stem":49,"__hash__":5598},"content\u002F2.learn\u002F1.tutorials\u002F07.typed-groups-and-schemas.md",{"type":209,"value":210,"toc":5564},"minimark",[211,215,240,257,283,286,336,427,430,438,444,783,788,794,860,881,883,890,904,1030,1033,1077,1089,1219,1222,1299,1302,1307,1328,1334,1398,1401,1403,1410,1438,1576,1713,1716,1723,1737,1777,1787,1859,1862,1864,1871,1881,1977,1980,1986,1994,2000,2052,2064,2257,2260,2262,2269,2280,2286,2349,2352,2364,2367,2385,2397,2399,2405,2411,2546,2715,2816,2818,3400,3403,3939,3942,4070,4073,4075,4079,4085,4156,4159,4273,4276,4300,4513,4516,4518,4522,4525,4616,4622,4624,4635,4638,4820,4823,4930,4932,4940,4954,4960,5183,5186,5300,5303,5393,5396,5398,5402,5514,5523,5541,5543,5560],[212,213,47],"h1",{"id":214},"typed-groups-and-schemas",[216,217,218,222,223,227,228,231,232,235,236,239],"p",{},[219,220,221],"strong",{},"Prerequisites:"," ",[224,225,226],"code",{},"01.why-laco.ipynb"," through ",[224,229,230],{},"05.loading-saving-cli.ipynb",". Familiarity with Python dataclasses (",[224,233,234],{},"@dataclass",", ",[224,237,238],{},"fields()",").",[216,241,242,222,245,248,249,252,253,256],{},[219,243,244],{},"Dependencies:",[224,246,247],{},"torch"," (for ",[224,250,251],{},"nn.Module"," and ",[224,254,255],{},"optim.Optimizer"," as nominal types).",[216,258,259,262,263,266,267,222,270,222,274,222,277,222,279,282],{},[224,260,261],{},"@L.params"," describes configs as a namespace of hyperparameters with interpolation support. That works for scalars. It does not work for ",[219,264,265],{},"swappable components",", where one field should be ",[224,268,269],{},"nn.ReLU",[271,272,273],"em",{},"or",[224,275,276],{},"nn.GELU",[271,278,273],{},[224,280,281],{},"nn.SiLU",", validated at configuration time. This notebook covers the mechanism that handles that case.",[216,284,285],{},"By the end you will understand:",[287,288,289,296,302,308,314,323,329],"ol",{},[290,291,292,293,295],"li",{},"Why ",[224,294,261],{}," is insufficient for swappable components.",[290,297,298,301],{},[224,299,300],{},"L.Group[T]",": declaring a typed set of alternatives.",[290,303,304,307],{},[224,305,306],{},"@L.config",": a structured schema that is a real dataclass.",[290,309,310,313],{},[224,311,312],{},"L.slot",": linking a schema field to a group.",[290,315,316,252,319,322],{},[224,317,318],{},"L.Defaults",[224,320,321],{},"L.bind",": choosing a default entry.",[290,324,325,328],{},[224,326,327],{},"L.chosen",": referencing the selected entry in the config body.",[290,330,331,332,335],{},"The complete ",[224,333,334],{},"typed\u002Fmlp.py"," example from first principles.",[337,338,343],"pre",{"className":339,"code":340,"language":341,"meta":342,"style":342},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","import dataclasses\n\nimport laco\nimport laco.language as L\nfrom omegaconf import OmegaConf\nfrom torch import nn, optim\n","python","",[224,344,345,358,365,373,394,408],{"__ignoreMap":342},[346,347,350,354],"span",{"class":348,"line":349},"line",1,[346,351,353],{"class":352},"sVHd0","import",[346,355,357],{"class":356},"su5hD"," dataclasses\n",[346,359,361],{"class":348,"line":360},2,[346,362,364],{"emptyLinePlaceholder":363},true,"\n",[346,366,368,370],{"class":348,"line":367},3,[346,369,353],{"class":352},[346,371,372],{"class":356}," laco\n",[346,374,376,378,381,385,388,391],{"class":348,"line":375},4,[346,377,353],{"class":352},[346,379,380],{"class":356}," laco",[346,382,384],{"class":383},"sP7_E",".",[346,386,198],{"class":387},"skxfh",[346,389,390],{"class":352}," as",[346,392,393],{"class":356}," L\n",[346,395,397,400,403,405],{"class":348,"line":396},5,[346,398,399],{"class":352},"from",[346,401,402],{"class":356}," omegaconf ",[346,404,353],{"class":352},[346,406,407],{"class":356}," OmegaConf\n",[346,409,411,413,416,418,421,424],{"class":348,"line":410},6,[346,412,399],{"class":352},[346,414,415],{"class":356}," torch ",[346,417,353],{"class":352},[346,419,420],{"class":356}," nn",[346,422,423],{"class":383},",",[346,425,426],{"class":356}," optim\n",[428,429],"hr",{},[431,432,434,435,437],"h2",{"id":433},"section-1-the-limitation-of-lparams-for-swappable-components","Section 1: The Limitation of ",[224,436,261],{}," for Swappable Components",[216,439,440,441,443],{},"Suppose the activation function in an MLP needs to be configurable. The naive\napproach with ",[224,442,261],{}," looks like this:",[337,445,447],{"className":339,"code":446,"language":341,"meta":342,"style":342},"@L.params\nclass hps_naive:\n    dim_in: int = 128\n    dim_hidden: int = 256\n    dim_out: int = 64\n    # PROBLEM: we want `activation` to be a *swappable component*, but @L.params\n    # is built for scalar hyperparameters. Storing a class object (nn.ReLU) is\n    # rejected when the params block is materialised into a DictConfig: OmegaConf\n    # only accepts primitive scalars, not arbitrary Python class references.\n    activation: type[nn.Module] = nn.ReLU\n\n# Statically, the attribute is just an interpolation string into the params block:\nprint(\"hps_naive.activation ->\", repr(hps_naive.activation))\n\n# Materialising the block surfaces the limitation: a class is not a valid value.\ntry:\n    OmegaConf.to_yaml(hps_naive())   # hps_naive() builds the dict; nn.ReLU is rejected\nexcept Exception as e:\n    print(f\"{type(e).__name__}: {e}\".splitlines()[0])\n    print(\"\\n=> @L.params cannot hold a swappable component (a class\u002Fobject).\")\n    print(\"   Section 2 fixes this with a typed L.Group instead.\")\n\n",[224,448,449,464,477,497,511,525,531,537,543,549,583,588,594,633,638,644,652,673,689,747,767],{"__ignoreMap":342},[346,450,451,455,459,461],{"class":348,"line":349},[346,452,454],{"class":453},"stp6e","@",[346,456,458],{"class":457},"sGLFI","L",[346,460,384],{"class":453},[346,462,463],{"class":457},"params\n",[346,465,466,470,474],{"class":348,"line":360},[346,467,469],{"class":468},"sbsja","class",[346,471,473],{"class":472},"sbgvK"," hps_naive",[346,475,476],{"class":383},":\n",[346,478,479,482,485,489,493],{"class":348,"line":367},[346,480,481],{"class":356},"    dim_in",[346,483,484],{"class":383},":",[346,486,488],{"class":487},"sZMiF"," int",[346,490,492],{"class":491},"smGrS"," =",[346,494,496],{"class":495},"srdBf"," 128\n",[346,498,499,502,504,506,508],{"class":348,"line":375},[346,500,501],{"class":356},"    dim_hidden",[346,503,484],{"class":383},[346,505,488],{"class":487},[346,507,492],{"class":491},[346,509,510],{"class":495}," 256\n",[346,512,513,516,518,520,522],{"class":348,"line":396},[346,514,515],{"class":356},"    dim_out",[346,517,484],{"class":383},[346,519,488],{"class":487},[346,521,492],{"class":491},[346,523,524],{"class":495}," 64\n",[346,526,527],{"class":348,"line":410},[346,528,530],{"class":529},"sutJx","    # PROBLEM: we want `activation` to be a *swappable component*, but @L.params\n",[346,532,534],{"class":348,"line":533},7,[346,535,536],{"class":529},"    # is built for scalar hyperparameters. Storing a class object (nn.ReLU) is\n",[346,538,540],{"class":348,"line":539},8,[346,541,542],{"class":529},"    # rejected when the params block is materialised into a DictConfig: OmegaConf\n",[346,544,546],{"class":348,"line":545},9,[346,547,548],{"class":529},"    # only accepts primitive scalars, not arbitrary Python class references.\n",[346,550,552,555,557,560,563,566,568,571,574,576,578,580],{"class":348,"line":551},10,[346,553,554],{"class":356},"    activation",[346,556,484],{"class":383},[346,558,559],{"class":356}," type",[346,561,562],{"class":383},"[",[346,564,565],{"class":356},"nn",[346,567,384],{"class":383},[346,569,570],{"class":387},"Module",[346,572,573],{"class":383},"]",[346,575,492],{"class":491},[346,577,420],{"class":356},[346,579,384],{"class":383},[346,581,582],{"class":387},"ReLU\n",[346,584,586],{"class":348,"line":585},11,[346,587,364],{"emptyLinePlaceholder":363},[346,589,591],{"class":348,"line":590},12,[346,592,593],{"class":529},"# Statically, the attribute is just an interpolation string into the params block:\n",[346,595,597,601,604,608,612,614,616,619,621,625,627,630],{"class":348,"line":596},13,[346,598,600],{"class":599},"sptTA","print",[346,602,603],{"class":383},"(",[346,605,607],{"class":606},"sjJ54","\"",[346,609,611],{"class":610},"s_sjI","hps_naive.activation ->",[346,613,607],{"class":606},[346,615,423],{"class":383},[346,617,618],{"class":599}," repr",[346,620,603],{"class":383},[346,622,624],{"class":623},"slqww","hps_naive",[346,626,384],{"class":383},[346,628,629],{"class":387},"activation",[346,631,632],{"class":383},"))\n",[346,634,636],{"class":348,"line":635},14,[346,637,364],{"emptyLinePlaceholder":363},[346,639,641],{"class":348,"line":640},15,[346,642,643],{"class":529},"# Materialising the block surfaces the limitation: a class is not a valid value.\n",[346,645,647,650],{"class":348,"line":646},16,[346,648,649],{"class":352},"try",[346,651,476],{"class":383},[346,653,655,658,660,663,665,667,670],{"class":348,"line":654},17,[346,656,657],{"class":356},"    OmegaConf",[346,659,384],{"class":383},[346,661,662],{"class":623},"to_yaml",[346,664,603],{"class":383},[346,666,624],{"class":623},[346,668,669],{"class":383},"())",[346,671,672],{"class":529},"   # hps_naive() builds the dict; nn.ReLU is rejected\n",[346,674,676,679,682,684,687],{"class":348,"line":675},18,[346,677,678],{"class":352},"except",[346,680,681],{"class":487}," Exception",[346,683,390],{"class":352},[346,685,686],{"class":356}," e",[346,688,476],{"class":383},[346,690,692,695,697,700,702,705,708,710,713,715,719,722,725,727,729,731,733,735,738,741,744],{"class":348,"line":691},19,[346,693,694],{"class":599},"    print",[346,696,603],{"class":383},[346,698,699],{"class":468},"f",[346,701,607],{"class":610},[346,703,704],{"class":495},"{",[346,706,707],{"class":487},"type",[346,709,603],{"class":383},[346,711,712],{"class":623},"e",[346,714,239],{"class":383},[346,716,718],{"class":717},"s_hVV","__name__",[346,720,721],{"class":495},"}",[346,723,724],{"class":610},": ",[346,726,704],{"class":495},[346,728,712],{"class":623},[346,730,721],{"class":495},[346,732,607],{"class":610},[346,734,384],{"class":383},[346,736,737],{"class":623},"splitlines",[346,739,740],{"class":383},"()[",[346,742,743],{"class":495},"0",[346,745,746],{"class":383},"])\n",[346,748,750,752,754,756,759,762,764],{"class":348,"line":749},20,[346,751,694],{"class":599},[346,753,603],{"class":383},[346,755,607],{"class":606},[346,757,758],{"class":717},"\\n",[346,760,761],{"class":610},"=> @L.params cannot hold a swappable component (a class\u002Fobject).",[346,763,607],{"class":606},[346,765,766],{"class":383},")\n",[346,768,770,772,774,776,779,781],{"class":348,"line":769},21,[346,771,694],{"class":599},[346,773,603],{"class":383},[346,775,607],{"class":606},[346,777,778],{"class":610},"   Section 2 fixes this with a typed L.Group instead.",[346,780,607],{"class":606},[346,782,766],{"class":383},[784,785],"docyard-notebook-output",{"data":786,"kind":787},"aHBzX25haXZlLmFjdGl2YXRpb24gLT4gJyR7aHBzX25haXZlLmFjdGl2YXRpb259JwpVbnN1cHBvcnRlZFZhbHVlVHlwZTogVmFsdWUgJ1JlTFUnIGlzIG5vdCBhIHN1cHBvcnRlZCBwcmltaXRpdmUgdHlwZQoKPT4gQEwucGFyYW1zIGNhbm5vdCBob2xkIGEgc3dhcHBhYmxlIGNvbXBvbmVudCAoYSBjbGFzcy9vYmplY3QpLgogICBTZWN0aW9uIDIgZml4ZXMgdGhpcyB3aXRoIGEgdHlwZWQgTC5Hcm91cCBpbnN0ZWFkLgo=","stream",[216,789,790,791,793],{},"With ",[224,792,261],{}," there are three concrete problems:",[795,796,797,810],"table",{},[798,799,800],"thead",{},[801,802,803,807],"tr",{},[804,805,806],"th",{},"Problem",[804,808,809],{},"Detail",[811,812,813,828,842],"tbody",{},[801,814,815,821],{},[816,817,818],"td",{},[219,819,820],{},"No validated choice set",[816,822,823,824,827],{},"There is no enforcement that ",[224,825,826],{},"activation=gelu"," is a valid alternative; any string is accepted until runtime crashes",[801,829,830,835],{},[816,831,832],{},[219,833,834],{},"Runtime-only errors",[816,836,837,838,841],{},"A typo like ",[224,839,840],{},"activation=relu_typo"," fails at runtime, inside a training job, not at edit time",[801,843,844,849],{},[816,845,846],{},[219,847,848],{},"No static type checking on alternatives",[816,850,851,852,855,856,859],{},"The IDE cannot autocomplete ",[224,853,854],{},"ActivationGroup.relu"," because ",[224,857,858],{},"ActivationGroup"," does not exist",[216,861,862,863,865,866,869,870,873,874,876,877,880],{},"The ",[224,864,261],{}," mechanism is designed for ",[271,867,868],{},"scalar hyperparameters"," (learning rate, batch\nsize, number of layers). For ",[271,871,872],{},"swappable object nodes",", a choice among several\npre-configured ",[224,875,251],{}," variants, the ",[219,878,879],{},"Group API"," is what's needed.",[428,882],{},[431,884,886,887,889],{"id":885},"section-2-lgroupt-declaring-a-config-group","Section 2: ",[224,888,300],{},", Declaring a Config Group",[216,891,892,893,896,897,900,901,903],{},"A ",[271,894,895],{},"config group"," is a named set of interchangeable config nodes that all instantiate to\nthe same type ",[224,898,899],{},"T",". Subclassing ",[224,902,300],{}," declares such a group:",[337,905,907],{"className":339,"code":906,"language":341,"meta":342,"style":342},"class ActivationGroup(L.Group[nn.Module]):\n    \"\"\"Swappable activation functions.\"\"\"\n\n    relu = L.call(nn.ReLU)()\n    gelu = L.call(nn.GELU)()\n    silu = L.call(nn.SiLU)()\n",[224,908,909,936,949,953,981,1006],{"__ignoreMap":342},[346,910,911,913,916,918,920,922,925,927,929,931,933],{"class":348,"line":349},[346,912,469],{"class":468},[346,914,915],{"class":472}," ActivationGroup",[346,917,603],{"class":383},[346,919,458],{"class":472},[346,921,384],{"class":383},[346,923,924],{"class":387},"Group",[346,926,562],{"class":383},[346,928,565],{"class":387},[346,930,384],{"class":383},[346,932,570],{"class":387},[346,934,935],{"class":383},"]):\n",[346,937,938,942,946],{"class":348,"line":360},[346,939,941],{"class":940},"s2W-s","    \"\"\"",[346,943,945],{"class":944},"sithA","Swappable activation functions.",[346,947,948],{"class":940},"\"\"\"\n",[346,950,951],{"class":348,"line":367},[346,952,364],{"emptyLinePlaceholder":363},[346,954,955,958,961,964,966,969,971,973,975,978],{"class":348,"line":375},[346,956,957],{"class":356},"    relu ",[346,959,960],{"class":491},"=",[346,962,963],{"class":356}," L",[346,965,384],{"class":383},[346,967,968],{"class":623},"call",[346,970,603],{"class":383},[346,972,565],{"class":623},[346,974,384],{"class":383},[346,976,977],{"class":387},"ReLU",[346,979,980],{"class":383},")()\n",[346,982,983,986,988,990,992,994,996,998,1000,1004],{"class":348,"line":396},[346,984,985],{"class":356},"    gelu ",[346,987,960],{"class":491},[346,989,963],{"class":356},[346,991,384],{"class":383},[346,993,968],{"class":623},[346,995,603],{"class":383},[346,997,565],{"class":623},[346,999,384],{"class":383},[346,1001,1003],{"class":1002},"swQdS","GELU",[346,1005,980],{"class":383},[346,1007,1008,1011,1013,1015,1017,1019,1021,1023,1025,1028],{"class":348,"line":410},[346,1009,1010],{"class":356},"    silu ",[346,1012,960],{"class":491},[346,1014,963],{"class":356},[346,1016,384],{"class":383},[346,1018,968],{"class":623},[346,1020,603],{"class":383},[346,1022,565],{"class":623},[346,1024,384],{"class":383},[346,1026,1027],{"class":387},"SiLU",[346,1029,980],{"class":383},[216,1031,1032],{},"What just happened at class-creation time?",[287,1034,1035,1041,1060],{},[290,1036,1037,1040],{},[224,1038,1039],{},"Group.__init_subclass__"," fired and walked every non-dunder class attribute.",[290,1042,1043,1044,1047,1048,1051,1052,1055,1056,1059],{},"Each attribute whose value is a ",[224,1045,1046],{},"DictConfig"," node (produced by ",[224,1049,1050],{},"L.call",") was\nregistered into Hydra's ",[224,1053,1054],{},"ConfigStore"," under\n",[224,1057,1058],{},"group=\"activationgroup\", name=\"relu\""," etc.",[290,1061,892,1062,1065,1066,1069,1070,1073,1074,1076],{},[224,1063,1064],{},"GroupEntry(group, name, node)"," record was stored in the module-level\n",[224,1067,1068],{},"_ENTRY_ORIGINS"," dict, keyed by the node's ",[224,1071,1072],{},"id()",", so ",[224,1075,321],{}," can later recover\nthe group\u002Fname from the entry value alone.",[216,1078,1079,1080,724,1083,1085,1086,384],{},"The group name defaults to ",[224,1081,1082],{},"cls.__name__.lower()",[224,1084,858],{}," → ",[224,1087,1088],{},"\"activationgroup\"",[337,1090,1092],{"className":339,"code":1091,"language":341,"meta":342,"style":342},"# The class attribute IS the DictConfig node (lie-typed as nn.Module)\nprint(\"type(ActivationGroup.relu):\", type(ActivationGroup.relu))\n\n# Dump shows the recipe that will be instantiated\nprint(\"\\n--- ActivationGroup.relu ---\")\nprint(laco.dump(ActivationGroup.relu))\n\nprint(\"--- ActivationGroup.gelu ---\")\nprint(laco.dump(ActivationGroup.gelu))\n",[224,1093,1094,1099,1127,1131,1136,1153,1177,1181,1196],{"__ignoreMap":342},[346,1095,1096],{"class":348,"line":349},[346,1097,1098],{"class":529},"# The class attribute IS the DictConfig node (lie-typed as nn.Module)\n",[346,1100,1101,1103,1105,1107,1110,1112,1114,1116,1118,1120,1122,1125],{"class":348,"line":360},[346,1102,600],{"class":599},[346,1104,603],{"class":383},[346,1106,607],{"class":606},[346,1108,1109],{"class":610},"type(ActivationGroup.relu):",[346,1111,607],{"class":606},[346,1113,423],{"class":383},[346,1115,559],{"class":487},[346,1117,603],{"class":383},[346,1119,858],{"class":623},[346,1121,384],{"class":383},[346,1123,1124],{"class":387},"relu",[346,1126,632],{"class":383},[346,1128,1129],{"class":348,"line":367},[346,1130,364],{"emptyLinePlaceholder":363},[346,1132,1133],{"class":348,"line":375},[346,1134,1135],{"class":529},"# Dump shows the recipe that will be instantiated\n",[346,1137,1138,1140,1142,1144,1146,1149,1151],{"class":348,"line":396},[346,1139,600],{"class":599},[346,1141,603],{"class":383},[346,1143,607],{"class":606},[346,1145,758],{"class":717},[346,1147,1148],{"class":610},"--- ActivationGroup.relu ---",[346,1150,607],{"class":606},[346,1152,766],{"class":383},[346,1154,1155,1157,1159,1162,1164,1167,1169,1171,1173,1175],{"class":348,"line":410},[346,1156,600],{"class":599},[346,1158,603],{"class":383},[346,1160,1161],{"class":623},"laco",[346,1163,384],{"class":383},[346,1165,1166],{"class":623},"dump",[346,1168,603],{"class":383},[346,1170,858],{"class":623},[346,1172,384],{"class":383},[346,1174,1124],{"class":387},[346,1176,632],{"class":383},[346,1178,1179],{"class":348,"line":533},[346,1180,364],{"emptyLinePlaceholder":363},[346,1182,1183,1185,1187,1189,1192,1194],{"class":348,"line":539},[346,1184,600],{"class":599},[346,1186,603],{"class":383},[346,1188,607],{"class":606},[346,1190,1191],{"class":610},"--- ActivationGroup.gelu ---",[346,1193,607],{"class":606},[346,1195,766],{"class":383},[346,1197,1198,1200,1202,1204,1206,1208,1210,1212,1214,1217],{"class":348,"line":545},[346,1199,600],{"class":599},[346,1201,603],{"class":383},[346,1203,1161],{"class":623},[346,1205,384],{"class":383},[346,1207,1166],{"class":623},[346,1209,603],{"class":383},[346,1211,858],{"class":623},[346,1213,384],{"class":383},[346,1215,1216],{"class":387},"gelu",[346,1218,632],{"class":383},[784,1220],{"data":1221,"kind":787},"dHlwZShBY3RpdmF0aW9uR3JvdXAucmVsdSk6IDxjbGFzcyAnb21lZ2Fjb25mLmRpY3Rjb25maWcuRGljdENvbmZpZyc+CgotLS0gQWN0aXZhdGlvbkdyb3VwLnJlbHUgLS0tCntfY29udmVydF86IGFsbCwgX2xhY29fOiAxLCBfdGFyZ2V0XzogdG9yY2gubm4uUmVMVX0KCi0tLSBBY3RpdmF0aW9uR3JvdXAuZ2VsdSAtLS0Ke19jb252ZXJ0XzogYWxsLCBfbGFjb186IDEsIF90YXJnZXRfOiB0b3JjaC5ubi5HRUxVfQoK",[337,1223,1225],{"className":339,"code":1224,"language":341,"meta":342,"style":342},"# Iterate over all registered entries\nfor entry in ActivationGroup.entries():\n    print(f\"  group={entry.group!r}  name={entry.name!r}\")\n",[224,1226,1227,1232,1253],{"__ignoreMap":342},[346,1228,1229],{"class":348,"line":349},[346,1230,1231],{"class":529},"# Iterate over all registered entries\n",[346,1233,1234,1237,1240,1243,1245,1247,1250],{"class":348,"line":360},[346,1235,1236],{"class":352},"for",[346,1238,1239],{"class":356}," entry ",[346,1241,1242],{"class":352},"in",[346,1244,915],{"class":356},[346,1246,384],{"class":383},[346,1248,1249],{"class":623},"entries",[346,1251,1252],{"class":383},"():\n",[346,1254,1255,1257,1259,1261,1264,1266,1269,1271,1274,1277,1279,1282,1284,1286,1288,1291,1293,1295,1297],{"class":348,"line":367},[346,1256,694],{"class":599},[346,1258,603],{"class":383},[346,1260,699],{"class":468},[346,1262,1263],{"class":610},"\"  group=",[346,1265,704],{"class":495},[346,1267,1268],{"class":623},"entry",[346,1270,384],{"class":383},[346,1272,1273],{"class":387},"group",[346,1275,1276],{"class":468},"!r",[346,1278,721],{"class":495},[346,1280,1281],{"class":610},"  name=",[346,1283,704],{"class":495},[346,1285,1268],{"class":623},[346,1287,384],{"class":383},[346,1289,1290],{"class":387},"name",[346,1292,1276],{"class":468},[346,1294,721],{"class":495},[346,1296,607],{"class":610},[346,1298,766],{"class":383},[784,1300],{"data":1301,"kind":787},"ICBncm91cD0nYWN0aXZhdGlvbmdyb3VwJyAgbmFtZT0ncmVsdScKICBncm91cD0nYWN0aXZhdGlvbmdyb3VwJyAgbmFtZT0nZ2VsdScKICBncm91cD0nYWN0aXZhdGlvbmdyb3VwJyAgbmFtZT0nc2lsdScK",[1303,1304,1306],"h3",{"id":1305},"static-safety","Static safety",[216,1308,1309,1310,1312,1313,1315,1316,1319,1320,1323,1324,1327],{},"Because ",[224,1311,854],{}," is a real class attribute (lie-typed as ",[224,1314,251],{},"),\na typo like ",[224,1317,1318],{},"ActivationGroup.relu_typo"," raises ",[224,1321,1322],{},"AttributeError"," immediately in Python\n",[271,1325,1326],{},"and"," is a static error in pyright, before you ever run the training script.",[216,1329,1330,1331,1333],{},"Compare this to ",[224,1332,261],{}," where any string could silently reach the YAML override\nmachinery.",[337,1335,1337],{"className":339,"code":1336,"language":341,"meta":342,"style":342},"# Typo is caught immediately at import time (or by pyright at edit time)\ntry:\n    _ = ActivationGroup.relu_typo\nexcept AttributeError as e:\n    print(f\"AttributeError: {e}\")\n",[224,1338,1339,1344,1350,1364,1377],{"__ignoreMap":342},[346,1340,1341],{"class":348,"line":349},[346,1342,1343],{"class":529},"# Typo is caught immediately at import time (or by pyright at edit time)\n",[346,1345,1346,1348],{"class":348,"line":360},[346,1347,649],{"class":352},[346,1349,476],{"class":383},[346,1351,1352,1355,1357,1359,1361],{"class":348,"line":367},[346,1353,1354],{"class":356},"    _ ",[346,1356,960],{"class":491},[346,1358,915],{"class":356},[346,1360,384],{"class":383},[346,1362,1363],{"class":387},"relu_typo\n",[346,1365,1366,1368,1371,1373,1375],{"class":348,"line":375},[346,1367,678],{"class":352},[346,1369,1370],{"class":487}," AttributeError",[346,1372,390],{"class":352},[346,1374,686],{"class":356},[346,1376,476],{"class":383},[346,1378,1379,1381,1383,1385,1388,1390,1392,1394,1396],{"class":348,"line":396},[346,1380,694],{"class":599},[346,1382,603],{"class":383},[346,1384,699],{"class":468},[346,1386,1387],{"class":610},"\"AttributeError: ",[346,1389,704],{"class":495},[346,1391,712],{"class":623},[346,1393,721],{"class":495},[346,1395,607],{"class":610},[346,1397,766],{"class":383},[784,1399],{"data":1400,"kind":787},"QXR0cmlidXRlRXJyb3I6IHR5cGUgb2JqZWN0ICdBY3RpdmF0aW9uR3JvdXAnIGhhcyBubyBhdHRyaWJ1dGUgJ3JlbHVfdHlwbycK",[428,1402],{},[431,1404,1406,1407,1409],{"id":1405},"section-3-lconfig-the-typed-schema","Section 3: ",[224,1408,306],{},", The Typed Schema",[216,1411,892,1412,1415,1416,1418,1419,222,1426,1429,1430,1433,1434,1437],{},[271,1413,1414],{},"schema"," describes the hyperparameter fields for a model. ",[224,1417,306],{}," is a\n",[1420,1421,1425],"a",{"href":1422,"rel":1423},"https:\u002F\u002Fpeps.python.org\u002Fpep-0681\u002F",[1424],"nofollow","PEP 681",[224,1427,1428],{},"dataclass_transform"," decorator: it applies\n",[224,1431,1432],{},"dataclasses.dataclass"," under the hood, so the result is a real dataclass with\nIDE-visible fields, but it also handles the special ",[224,1435,1436],{},"L.slot(...)"," field specifier.",[337,1439,1441],{"className":339,"code":1440,"language":341,"meta":342,"style":342},"@L.config\nclass MLPSchema:\n    \"\"\"Typed configuration schema for the MLP.\"\"\"\n\n    dim_in:     int       = 128\n    dim_out:    int       = 128\n    dim_hidden: int       = 256\n    num_layers: int       = 3\n    # L.slot links this field to ActivationGroup.\n    # At runtime the default is rewritten to the string \"${activation}\"\n    # (an OmegaConf interpolation that the defaults list fills in).\n    # Statically, pyright sees type nn.Module — the lie-typing contract.\n    activation: nn.Module = L.slot(ActivationGroup)\n",[224,1442,1443,1454,1463,1472,1476,1490,1503,1515,1529,1534,1539,1544,1549],{"__ignoreMap":342},[346,1444,1445,1447,1449,1451],{"class":348,"line":349},[346,1446,454],{"class":453},[346,1448,458],{"class":457},[346,1450,384],{"class":453},[346,1452,1453],{"class":457},"config\n",[346,1455,1456,1458,1461],{"class":348,"line":360},[346,1457,469],{"class":468},[346,1459,1460],{"class":472}," MLPSchema",[346,1462,476],{"class":383},[346,1464,1465,1467,1470],{"class":348,"line":367},[346,1466,941],{"class":940},[346,1468,1469],{"class":944},"Typed configuration schema for the MLP.",[346,1471,948],{"class":940},[346,1473,1474],{"class":348,"line":375},[346,1475,364],{"emptyLinePlaceholder":363},[346,1477,1478,1480,1482,1485,1488],{"class":348,"line":396},[346,1479,481],{"class":356},[346,1481,484],{"class":383},[346,1483,1484],{"class":487},"     int",[346,1486,1487],{"class":491},"       =",[346,1489,496],{"class":495},[346,1491,1492,1494,1496,1499,1501],{"class":348,"line":410},[346,1493,515],{"class":356},[346,1495,484],{"class":383},[346,1497,1498],{"class":487},"    int",[346,1500,1487],{"class":491},[346,1502,496],{"class":495},[346,1504,1505,1507,1509,1511,1513],{"class":348,"line":533},[346,1506,501],{"class":356},[346,1508,484],{"class":383},[346,1510,488],{"class":487},[346,1512,1487],{"class":491},[346,1514,510],{"class":495},[346,1516,1517,1520,1522,1524,1526],{"class":348,"line":539},[346,1518,1519],{"class":356},"    num_layers",[346,1521,484],{"class":383},[346,1523,488],{"class":487},[346,1525,1487],{"class":491},[346,1527,1528],{"class":495}," 3\n",[346,1530,1531],{"class":348,"line":545},[346,1532,1533],{"class":529},"    # L.slot links this field to ActivationGroup.\n",[346,1535,1536],{"class":348,"line":551},[346,1537,1538],{"class":529},"    # At runtime the default is rewritten to the string \"${activation}\"\n",[346,1540,1541],{"class":348,"line":585},[346,1542,1543],{"class":529},"    # (an OmegaConf interpolation that the defaults list fills in).\n",[346,1545,1546],{"class":348,"line":590},[346,1547,1548],{"class":529},"    # Statically, pyright sees type nn.Module — the lie-typing contract.\n",[346,1550,1551,1553,1555,1557,1559,1561,1563,1565,1567,1570,1572,1574],{"class":348,"line":596},[346,1552,554],{"class":356},[346,1554,484],{"class":383},[346,1556,420],{"class":356},[346,1558,384],{"class":383},[346,1560,570],{"class":387},[346,1562,492],{"class":491},[346,1564,963],{"class":356},[346,1566,384],{"class":383},[346,1568,1569],{"class":623},"slot",[346,1571,603],{"class":383},[346,1573,858],{"class":623},[346,1575,766],{"class":383},[337,1577,1579],{"className":339,"code":1578,"language":341,"meta":342,"style":342},"# @L.config applied dataclasses.dataclass — MLPSchema is a real dataclass\nprint(\"Is dataclass:\", dataclasses.is_dataclass(MLPSchema))\n\nprint(\"\\nFields:\")\nfor f in dataclasses.fields(MLPSchema):\n    print(f\"  {f.name}: {f.type}  default={f.default!r}\")\n",[224,1580,1581,1586,1616,1620,1637,1660],{"__ignoreMap":342},[346,1582,1583],{"class":348,"line":349},[346,1584,1585],{"class":529},"# @L.config applied dataclasses.dataclass — MLPSchema is a real dataclass\n",[346,1587,1588,1590,1592,1594,1597,1599,1601,1604,1606,1609,1611,1614],{"class":348,"line":360},[346,1589,600],{"class":599},[346,1591,603],{"class":383},[346,1593,607],{"class":606},[346,1595,1596],{"class":610},"Is dataclass:",[346,1598,607],{"class":606},[346,1600,423],{"class":383},[346,1602,1603],{"class":623}," dataclasses",[346,1605,384],{"class":383},[346,1607,1608],{"class":623},"is_dataclass",[346,1610,603],{"class":383},[346,1612,1613],{"class":623},"MLPSchema",[346,1615,632],{"class":383},[346,1617,1618],{"class":348,"line":367},[346,1619,364],{"emptyLinePlaceholder":363},[346,1621,1622,1624,1626,1628,1630,1633,1635],{"class":348,"line":375},[346,1623,600],{"class":599},[346,1625,603],{"class":383},[346,1627,607],{"class":606},[346,1629,758],{"class":717},[346,1631,1632],{"class":610},"Fields:",[346,1634,607],{"class":606},[346,1636,766],{"class":383},[346,1638,1639,1641,1644,1646,1648,1650,1653,1655,1657],{"class":348,"line":396},[346,1640,1236],{"class":352},[346,1642,1643],{"class":356}," f ",[346,1645,1242],{"class":352},[346,1647,1603],{"class":356},[346,1649,384],{"class":383},[346,1651,1652],{"class":623},"fields",[346,1654,603],{"class":383},[346,1656,1613],{"class":623},[346,1658,1659],{"class":383},"):\n",[346,1661,1662,1664,1666,1668,1671,1673,1675,1677,1679,1681,1683,1685,1687,1689,1691,1693,1696,1698,1700,1702,1705,1707,1709,1711],{"class":348,"line":410},[346,1663,694],{"class":599},[346,1665,603],{"class":383},[346,1667,699],{"class":468},[346,1669,1670],{"class":610},"\"  ",[346,1672,704],{"class":495},[346,1674,699],{"class":623},[346,1676,384],{"class":383},[346,1678,1290],{"class":387},[346,1680,721],{"class":495},[346,1682,724],{"class":610},[346,1684,704],{"class":495},[346,1686,699],{"class":623},[346,1688,384],{"class":383},[346,1690,707],{"class":387},[346,1692,721],{"class":495},[346,1694,1695],{"class":610},"  default=",[346,1697,704],{"class":495},[346,1699,699],{"class":623},[346,1701,384],{"class":383},[346,1703,1704],{"class":387},"default",[346,1706,1276],{"class":468},[346,1708,721],{"class":495},[346,1710,607],{"class":610},[346,1712,766],{"class":383},[784,1714],{"data":1715,"kind":787},"SXMgZGF0YWNsYXNzOiBUcnVlCgpGaWVsZHM6CiAgZGltX2luOiA8Y2xhc3MgJ2ludCc+ICBkZWZhdWx0PTEyOAogIGRpbV9vdXQ6IDxjbGFzcyAnaW50Jz4gIGRlZmF1bHQ9MTI4CiAgZGltX2hpZGRlbjogPGNsYXNzICdpbnQnPiAgZGVmYXVsdD0yNTYKICBudW1fbGF5ZXJzOiA8Y2xhc3MgJ2ludCc+ICBkZWZhdWx0PTMKICBhY3RpdmF0aW9uOiA8Y2xhc3MgJ3RvcmNoLm5uLm1vZHVsZXMubW9kdWxlLk1vZHVsZSc+ICBkZWZhdWx0PScke2FjdGl2YXRpb259Jwo=",[1303,1717,1719,1720,1722],{"id":1718},"how-lslot-works","How ",[224,1721,312],{}," works",[216,1724,1725,1726,1728,1729,1732,1733,1736],{},"When ",[224,1727,306],{}," is applied it calls ",[224,1730,1731],{},"_resolve_slots(target)",", which walks the class\nbody looking for ",[224,1734,1735],{},"_SlotSpec"," instances. For each one it:",[287,1738,1739,1752,1767],{},[290,1740,1741,1742,1745,1746,1748,1749,239],{},"Infers the ",[219,1743,1744],{},"package name"," from the field name (e.g. field ",[224,1747,629],{}," → package\n",[224,1750,1751],{},"\"activation\"",[290,1753,1754,1755,1758,1759,1762,1763,1766],{},"Rewrites the class attribute to a ",[224,1756,1757],{},"_SlotRef",", which is a ",[224,1760,1761],{},"str"," subclass holding\n",[224,1764,1765],{},"\"${activation}\"",", an OmegaConf variable interpolation.",[290,1768,1769,1770,1773,1774,1776],{},"Stores the originating group name (",[224,1771,1772],{},"activationgroup",") so ",[224,1775,321],{}," can validate\nthat the bound entry actually belongs to the right group.",[216,1778,1779,1780,1782,1783,1786],{},"When Hydra composes a config that includes both the schema and a defaults-list entry\nfor ",[224,1781,1772],{},", the interpolation ",[224,1784,1785],{},"${activation}"," resolves to the composed entry\nnode.",[337,1788,1790],{"className":339,"code":1789,"language":341,"meta":342,"style":342},"# After @L.config the field default is the interpolation string\nraw_default = MLPSchema.__dataclass_fields__[\"activation\"].default\nprint(\"activation default (runtime):\", repr(raw_default))\n# Pyright \u002F IDE sees: nn.Module (the lie)\n# Python holds: _SlotRef('${activation}', group='activationgroup')\n",[224,1791,1792,1797,1825,1849,1854],{"__ignoreMap":342},[346,1793,1794],{"class":348,"line":349},[346,1795,1796],{"class":529},"# After @L.config the field default is the interpolation string\n",[346,1798,1799,1802,1804,1806,1808,1811,1813,1815,1817,1819,1822],{"class":348,"line":360},[346,1800,1801],{"class":356},"raw_default ",[346,1803,960],{"class":491},[346,1805,1460],{"class":356},[346,1807,384],{"class":383},[346,1809,1810],{"class":387},"__dataclass_fields__",[346,1812,562],{"class":383},[346,1814,607],{"class":606},[346,1816,629],{"class":610},[346,1818,607],{"class":606},[346,1820,1821],{"class":383},"].",[346,1823,1824],{"class":387},"default\n",[346,1826,1827,1829,1831,1833,1836,1838,1840,1842,1844,1847],{"class":348,"line":367},[346,1828,600],{"class":599},[346,1830,603],{"class":383},[346,1832,607],{"class":606},[346,1834,1835],{"class":610},"activation default (runtime):",[346,1837,607],{"class":606},[346,1839,423],{"class":383},[346,1841,618],{"class":599},[346,1843,603],{"class":383},[346,1845,1846],{"class":623},"raw_default",[346,1848,632],{"class":383},[346,1850,1851],{"class":348,"line":375},[346,1852,1853],{"class":529},"# Pyright \u002F IDE sees: nn.Module (the lie)\n",[346,1855,1856],{"class":348,"line":396},[346,1857,1858],{"class":529},"# Python holds: _SlotRef('${activation}', group='activationgroup')\n",[784,1860],{"data":1861,"kind":787},"YWN0aXZhdGlvbiBkZWZhdWx0IChydW50aW1lKTogJyR7YWN0aXZhdGlvbn0nCg==",[428,1863],{},[431,1865,1867,1868,1870],{"id":1866},"section-4-ldefaults-the-defaults-list","Section 4: ",[224,1869,318],{},", The Defaults List",[216,1872,1873,1874,1876,1877,1880],{},"Hydra's defaults list tells the composition engine which entries to merge, and in what\norder. ",[224,1875,318],{}," produces a validated Python object that Laco serializes into the\n",[224,1878,1879],{},"defaults"," key recognized by Hydra.",[337,1882,1884],{"className":339,"code":1883,"language":341,"meta":342,"style":342},"defaults = L.Defaults(\n    L.self_,                                            # include this file's own fields\n    L.bind(MLPSchema.activation, ActivationGroup.relu), # activation slot → relu entry\n)\n\nprint(\"defaults:\", defaults)\n",[224,1885,1886,1903,1918,1949,1953,1957],{"__ignoreMap":342},[346,1887,1888,1891,1893,1895,1897,1900],{"class":348,"line":349},[346,1889,1890],{"class":356},"defaults ",[346,1892,960],{"class":491},[346,1894,963],{"class":356},[346,1896,384],{"class":383},[346,1898,1899],{"class":623},"Defaults",[346,1901,1902],{"class":383},"(\n",[346,1904,1905,1908,1910,1913,1915],{"class":348,"line":360},[346,1906,1907],{"class":623},"    L",[346,1909,384],{"class":383},[346,1911,1912],{"class":387},"self_",[346,1914,423],{"class":383},[346,1916,1917],{"class":529},"                                            # include this file's own fields\n",[346,1919,1920,1922,1924,1927,1929,1931,1933,1935,1937,1939,1941,1943,1946],{"class":348,"line":367},[346,1921,1907],{"class":623},[346,1923,384],{"class":383},[346,1925,1926],{"class":623},"bind",[346,1928,603],{"class":383},[346,1930,1613],{"class":623},[346,1932,384],{"class":383},[346,1934,629],{"class":387},[346,1936,423],{"class":383},[346,1938,915],{"class":623},[346,1940,384],{"class":383},[346,1942,1124],{"class":387},[346,1944,1945],{"class":383},"),",[346,1947,1948],{"class":529}," # activation slot → relu entry\n",[346,1950,1951],{"class":348,"line":375},[346,1952,766],{"class":383},[346,1954,1955],{"class":348,"line":396},[346,1956,364],{"emptyLinePlaceholder":363},[346,1958,1959,1961,1963,1965,1968,1970,1972,1975],{"class":348,"line":410},[346,1960,600],{"class":599},[346,1962,603],{"class":383},[346,1964,607],{"class":606},[346,1966,1967],{"class":610},"defaults:",[346,1969,607],{"class":606},[346,1971,423],{"class":383},[346,1973,1974],{"class":623}," defaults",[346,1976,766],{"class":383},[784,1978],{"data":1979,"kind":787},"ZGVmYXVsdHM6IFsnX3NlbGZfJywgeydhY3RpdmF0aW9uZ3JvdXBAYWN0aXZhdGlvbic6ICdyZWx1J31dCg==",[1303,1981,1983,1984],{"id":1982},"step-by-step-breakdown-of-lbind","Step-by-step breakdown of ",[224,1985,321],{},[337,1987,1992],{"className":1988,"code":1990,"language":1991},[1989],"language-text","L.bind(MLPSchema.activation, ActivationGroup.relu)\n       ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^\n       slot (_SlotRef)       entry (DictConfig node)\n","text",[224,1993,1990],{"__ignoreMap":342},[216,1995,1996,1997,1999],{},"At runtime ",[224,1998,321],{}," does:",[287,2001,2002,2018,2036],{},[290,2003,2004,2007,2008,2011,2012,2014,2015,384],{},[219,2005,2006],{},"Resolve the entry origin",": looks up ",[224,2009,2010],{},"id(ActivationGroup.relu)"," in ",[224,2013,1068],{},"\nto recover ",[224,2016,2017],{},"GroupEntry(group='activationgroup', name='relu', node=...)",[290,2019,2020,2023,2024,2027,2028,2031,2032,2035],{},[219,2021,2022],{},"Validate the slot",": checks that the slot's stored group name\n(",[224,2025,2026],{},"MLPSchema.activation.group == 'activationgroup'",") matches the entry's group.\nA mismatch (e.g. ",[224,2029,2030],{},"L.bind(MLPSchema.activation, OptimGroup.adam)",") raises ",[224,2033,2034],{},"TypeError","\nimmediately, at config-authoring time.",[290,2037,2038,724,2044,2047,2048,2051],{},[219,2039,2040,2041],{},"Produce a ",[224,2042,2043],{},"DefaultsBinding",[224,2045,2046],{},"DefaultsBinding(group='activationgroup', name='relu')","\nwhich serializes to ",[224,2049,2050],{},"{\"activationgroup\": \"relu\"}"," in the Hydra defaults list.",[216,2053,2054,2055,2057,2058,2060,2061,2063],{},"The result: Hydra will compose the ",[224,2056,1124],{}," node into the package named ",[224,2059,1751],{},"\n(the field name), which the interpolation ",[224,2062,1785],{}," then resolves to.",[337,2065,2067],{"className":339,"code":2066,"language":341,"meta":342,"style":342},"# What happens if we accidentally bind the wrong group?\nclass OptimizerGroup(L.Group[optim.Optimizer]):\n    sgd  = L.partial(optim.SGD)(lr=1e-2, momentum=0.9)\n    adam = L.partial(optim.Adam)(lr=1e-3)\n\ntry:\n    bad = L.bind(MLPSchema.activation, OptimizerGroup.adam)\nexcept TypeError as e:\n    print(f\"TypeError: {e}\")\n",[224,2068,2069,2074,2101,2148,2181,2185,2191,2223,2236],{"__ignoreMap":342},[346,2070,2071],{"class":348,"line":349},[346,2072,2073],{"class":529},"# What happens if we accidentally bind the wrong group?\n",[346,2075,2076,2078,2081,2083,2085,2087,2089,2091,2094,2096,2099],{"class":348,"line":360},[346,2077,469],{"class":468},[346,2079,2080],{"class":472}," OptimizerGroup",[346,2082,603],{"class":383},[346,2084,458],{"class":472},[346,2086,384],{"class":383},[346,2088,924],{"class":387},[346,2090,562],{"class":383},[346,2092,2093],{"class":387},"optim",[346,2095,384],{"class":383},[346,2097,2098],{"class":387},"Optimizer",[346,2100,935],{"class":383},[346,2102,2103,2106,2108,2110,2112,2115,2117,2119,2121,2124,2127,2131,2133,2136,2138,2141,2143,2146],{"class":348,"line":367},[346,2104,2105],{"class":356},"    sgd  ",[346,2107,960],{"class":491},[346,2109,963],{"class":356},[346,2111,384],{"class":383},[346,2113,2114],{"class":623},"partial",[346,2116,603],{"class":383},[346,2118,2093],{"class":623},[346,2120,384],{"class":383},[346,2122,2123],{"class":1002},"SGD",[346,2125,2126],{"class":383},")(",[346,2128,2130],{"class":2129},"s99_P","lr",[346,2132,960],{"class":491},[346,2134,2135],{"class":495},"1e-2",[346,2137,423],{"class":383},[346,2139,2140],{"class":2129}," momentum",[346,2142,960],{"class":491},[346,2144,2145],{"class":495},"0.9",[346,2147,766],{"class":383},[346,2149,2150,2153,2155,2157,2159,2161,2163,2165,2167,2170,2172,2174,2176,2179],{"class":348,"line":375},[346,2151,2152],{"class":356},"    adam ",[346,2154,960],{"class":491},[346,2156,963],{"class":356},[346,2158,384],{"class":383},[346,2160,2114],{"class":623},[346,2162,603],{"class":383},[346,2164,2093],{"class":623},[346,2166,384],{"class":383},[346,2168,2169],{"class":387},"Adam",[346,2171,2126],{"class":383},[346,2173,2130],{"class":2129},[346,2175,960],{"class":491},[346,2177,2178],{"class":495},"1e-3",[346,2180,766],{"class":383},[346,2182,2183],{"class":348,"line":396},[346,2184,364],{"emptyLinePlaceholder":363},[346,2186,2187,2189],{"class":348,"line":410},[346,2188,649],{"class":352},[346,2190,476],{"class":383},[346,2192,2193,2196,2198,2200,2202,2204,2206,2208,2210,2212,2214,2216,2218,2221],{"class":348,"line":533},[346,2194,2195],{"class":356},"    bad ",[346,2197,960],{"class":491},[346,2199,963],{"class":356},[346,2201,384],{"class":383},[346,2203,1926],{"class":623},[346,2205,603],{"class":383},[346,2207,1613],{"class":623},[346,2209,384],{"class":383},[346,2211,629],{"class":387},[346,2213,423],{"class":383},[346,2215,2080],{"class":623},[346,2217,384],{"class":383},[346,2219,2220],{"class":387},"adam",[346,2222,766],{"class":383},[346,2224,2225,2227,2230,2232,2234],{"class":348,"line":539},[346,2226,678],{"class":352},[346,2228,2229],{"class":487}," TypeError",[346,2231,390],{"class":352},[346,2233,686],{"class":356},[346,2235,476],{"class":383},[346,2237,2238,2240,2242,2244,2247,2249,2251,2253,2255],{"class":348,"line":545},[346,2239,694],{"class":599},[346,2241,603],{"class":383},[346,2243,699],{"class":468},[346,2245,2246],{"class":610},"\"TypeError: ",[346,2248,704],{"class":495},[346,2250,712],{"class":623},[346,2252,721],{"class":495},[346,2254,607],{"class":610},[346,2256,766],{"class":383},[784,2258],{"data":2259,"kind":787},"VHlwZUVycm9yOiBiaW5kKCkgdHlwZSBtaXNtYXRjaDogc2xvdCBpcyBib3VuZCB0byBncm91cCAnYWN0aXZhdGlvbmdyb3VwJyBidXQgZW50cnkgJ2FkYW0nIGJlbG9uZ3MgdG8gZ3JvdXAgJ29wdGltaXplcmdyb3VwJy4K",[428,2261],{},[431,2263,2265,2266,2268],{"id":2264},"section-5-lchosen-referencing-the-selected-entry-in-the-config-body","Section 5: ",[224,2267,327],{},", Referencing the Selected Entry in the Config Body",[216,2270,2271,2272,2275,2276,2279],{},"Inside the model config body (the ",[224,2273,2274],{},"L.call(nn.Sequential)(...)"," tree), the code must\nreference whatever activation function was selected by the defaults list. Hard-coding\n",[224,2277,2278],{},"L.call(nn.ReLU)()"," here would defeat the whole point of having a swappable group.",[216,2281,2282,2285],{},[224,2283,2284],{},"L.chosen(ActivationGroup)"," produces exactly this: an OmegaConf interpolation that\nresolves to the composed activation entry at instantiation time.",[337,2287,2289],{"className":339,"code":2288,"language":341,"meta":342,"style":342},"activation_ref = L.chosen(ActivationGroup)\n\n# Runtime value: an interpolation string\nprint(\"runtime:\", repr(activation_ref))\n# Pyright sees: nn.Module (lie-typed as the group element type)\n",[224,2290,2291,2311,2315,2320,2344],{"__ignoreMap":342},[346,2292,2293,2296,2298,2300,2302,2305,2307,2309],{"class":348,"line":349},[346,2294,2295],{"class":356},"activation_ref ",[346,2297,960],{"class":491},[346,2299,963],{"class":356},[346,2301,384],{"class":383},[346,2303,2304],{"class":623},"chosen",[346,2306,603],{"class":383},[346,2308,858],{"class":623},[346,2310,766],{"class":383},[346,2312,2313],{"class":348,"line":360},[346,2314,364],{"emptyLinePlaceholder":363},[346,2316,2317],{"class":348,"line":367},[346,2318,2319],{"class":529},"# Runtime value: an interpolation string\n",[346,2321,2322,2324,2326,2328,2331,2333,2335,2337,2339,2342],{"class":348,"line":375},[346,2323,600],{"class":599},[346,2325,603],{"class":383},[346,2327,607],{"class":606},[346,2329,2330],{"class":610},"runtime:",[346,2332,607],{"class":606},[346,2334,423],{"class":383},[346,2336,618],{"class":599},[346,2338,603],{"class":383},[346,2340,2341],{"class":623},"activation_ref",[346,2343,632],{"class":383},[346,2345,2346],{"class":348,"line":396},[346,2347,2348],{"class":529},"# Pyright sees: nn.Module (lie-typed as the group element type)\n",[784,2350],{"data":2351,"kind":787},"cnVudGltZTogJyR7YWN0aXZhdGlvbmdyb3VwfScK",[216,2353,2354,2355,2357,2358,2361,2362,239],{},"The interpolation ",[224,2356,1785],{}," matches the package name derived from the\n",[224,2359,2360],{},"L.slot(ActivationGroup)"," field (whose field name is ",[224,2363,1751],{},[216,2365,2366],{},"When Hydra composes a config that has:",[2368,2369,2370,2376],"ul",{},[290,2371,2372,2375],{},[224,2373,2374],{},"schema.activation = \"${activation}\""," (from the slot)",[290,2377,2378,2381,2382,2384],{},[224,2379,2380],{},"defaults: [{activationgroup: relu}]"," (from ",[224,2383,321],{},")",[216,2386,2387,2388,2390,2391,2393,2394,2396],{},"then ",[224,2389,1785],{}," resolves to the full ",[224,2392,1124],{}," DictConfig node, so every ",[224,2395,327],{},"\ncall in the model body receives the correct activation.",[428,2398],{},[431,2400,2402,2403],{"id":2401},"section-6-full-walkthrough-typedmlppy","Section 6: Full Walkthrough, ",[224,2404,334],{},[216,2406,2407,2408,384],{},"Now that each primitive is covered, walk through the complete file line by\nline. The source lives at\n",[224,2409,2410],{},"sources\u002Flaco\u002Fexamples\u002Ftyped\u002Fmlp.py",[337,2412,2414],{"className":339,"code":2413,"language":341,"meta":342,"style":342},"# ------------------------------------------------------------------\n# Step 1 — Declare the group of swappable activations\n# ------------------------------------------------------------------\nclass ActivationGroup(L.Group[nn.Module]):  # type: ignore[no-redef]  # redefine for clarity\n    \"\"\"Swappable activation functions.\"\"\"\n    relu = L.call(nn.ReLU)()\n    gelu = L.call(nn.GELU)()\n    silu = L.call(nn.SiLU)()\n\n# Each attribute is a DictConfig node registered in the ConfigStore.\n# Group name: 'activationgroup'  (class name lower-cased)\n",[224,2415,2416,2421,2426,2430,2458,2466,2488,2510,2532,2536,2541],{"__ignoreMap":342},[346,2417,2418],{"class":348,"line":349},[346,2419,2420],{"class":529},"# ------------------------------------------------------------------\n",[346,2422,2423],{"class":348,"line":360},[346,2424,2425],{"class":529},"# Step 1 — Declare the group of swappable activations\n",[346,2427,2428],{"class":348,"line":367},[346,2429,2420],{"class":529},[346,2431,2432,2434,2436,2438,2440,2442,2444,2446,2448,2450,2452,2455],{"class":348,"line":375},[346,2433,469],{"class":468},[346,2435,915],{"class":472},[346,2437,603],{"class":383},[346,2439,458],{"class":472},[346,2441,384],{"class":383},[346,2443,924],{"class":387},[346,2445,562],{"class":383},[346,2447,565],{"class":387},[346,2449,384],{"class":383},[346,2451,570],{"class":387},[346,2453,2454],{"class":383},"]):",[346,2456,2457],{"class":529},"  # type: ignore[no-redef]  # redefine for clarity\n",[346,2459,2460,2462,2464],{"class":348,"line":396},[346,2461,941],{"class":940},[346,2463,945],{"class":944},[346,2465,948],{"class":940},[346,2467,2468,2470,2472,2474,2476,2478,2480,2482,2484,2486],{"class":348,"line":410},[346,2469,957],{"class":356},[346,2471,960],{"class":491},[346,2473,963],{"class":356},[346,2475,384],{"class":383},[346,2477,968],{"class":623},[346,2479,603],{"class":383},[346,2481,565],{"class":623},[346,2483,384],{"class":383},[346,2485,977],{"class":387},[346,2487,980],{"class":383},[346,2489,2490,2492,2494,2496,2498,2500,2502,2504,2506,2508],{"class":348,"line":533},[346,2491,985],{"class":356},[346,2493,960],{"class":491},[346,2495,963],{"class":356},[346,2497,384],{"class":383},[346,2499,968],{"class":623},[346,2501,603],{"class":383},[346,2503,565],{"class":623},[346,2505,384],{"class":383},[346,2507,1003],{"class":1002},[346,2509,980],{"class":383},[346,2511,2512,2514,2516,2518,2520,2522,2524,2526,2528,2530],{"class":348,"line":539},[346,2513,1010],{"class":356},[346,2515,960],{"class":491},[346,2517,963],{"class":356},[346,2519,384],{"class":383},[346,2521,968],{"class":623},[346,2523,603],{"class":383},[346,2525,565],{"class":623},[346,2527,384],{"class":383},[346,2529,1027],{"class":387},[346,2531,980],{"class":383},[346,2533,2534],{"class":348,"line":545},[346,2535,364],{"emptyLinePlaceholder":363},[346,2537,2538],{"class":348,"line":551},[346,2539,2540],{"class":529},"# Each attribute is a DictConfig node registered in the ConfigStore.\n",[346,2542,2543],{"class":348,"line":585},[346,2544,2545],{"class":529},"# Group name: 'activationgroup'  (class name lower-cased)\n",[337,2547,2549],{"className":339,"code":2548,"language":341,"meta":342,"style":342},"# ------------------------------------------------------------------\n# Step 2 — Declare the typed schema\n# ------------------------------------------------------------------\n@L.config\nclass MLPSchema:  # type: ignore[no-redef]\n    \"\"\"Typed schema for the MLP example.\"\"\"\n    dim_in:     int       = 128\n    dim_out:    int       = 128\n    dim_hidden: int       = 256\n    num_layers: int       = 3\n    activation: nn.Module = L.slot(ActivationGroup)\n    # After @L.config, the activation field default is '${activation}'.\n    # Pyright sees: nn.Module  (lie — matches the Group element type)\n\n# ------------------------------------------------------------------\n# Step 3 — Expose the schema as a module-level name\n# ------------------------------------------------------------------\n# When laco.load() reads this file, 'schema' is exposed as a fragment:\n#   laco.load('configs:\u002F\u002Fexamples\u002Ftyped\u002Fmlp.py#schema')\nschema = MLPSchema\n",[224,2550,2551,2555,2560,2564,2574,2585,2594,2606,2618,2630,2642,2668,2673,2678,2682,2686,2691,2695,2700,2705],{"__ignoreMap":342},[346,2552,2553],{"class":348,"line":349},[346,2554,2420],{"class":529},[346,2556,2557],{"class":348,"line":360},[346,2558,2559],{"class":529},"# Step 2 — Declare the typed schema\n",[346,2561,2562],{"class":348,"line":367},[346,2563,2420],{"class":529},[346,2565,2566,2568,2570,2572],{"class":348,"line":375},[346,2567,454],{"class":453},[346,2569,458],{"class":457},[346,2571,384],{"class":453},[346,2573,1453],{"class":457},[346,2575,2576,2578,2580,2582],{"class":348,"line":396},[346,2577,469],{"class":468},[346,2579,1460],{"class":472},[346,2581,484],{"class":383},[346,2583,2584],{"class":529},"  # type: ignore[no-redef]\n",[346,2586,2587,2589,2592],{"class":348,"line":410},[346,2588,941],{"class":940},[346,2590,2591],{"class":944},"Typed schema for the MLP example.",[346,2593,948],{"class":940},[346,2595,2596,2598,2600,2602,2604],{"class":348,"line":533},[346,2597,481],{"class":356},[346,2599,484],{"class":383},[346,2601,1484],{"class":487},[346,2603,1487],{"class":491},[346,2605,496],{"class":495},[346,2607,2608,2610,2612,2614,2616],{"class":348,"line":539},[346,2609,515],{"class":356},[346,2611,484],{"class":383},[346,2613,1498],{"class":487},[346,2615,1487],{"class":491},[346,2617,496],{"class":495},[346,2619,2620,2622,2624,2626,2628],{"class":348,"line":545},[346,2621,501],{"class":356},[346,2623,484],{"class":383},[346,2625,488],{"class":487},[346,2627,1487],{"class":491},[346,2629,510],{"class":495},[346,2631,2632,2634,2636,2638,2640],{"class":348,"line":551},[346,2633,1519],{"class":356},[346,2635,484],{"class":383},[346,2637,488],{"class":487},[346,2639,1487],{"class":491},[346,2641,1528],{"class":495},[346,2643,2644,2646,2648,2650,2652,2654,2656,2658,2660,2662,2664,2666],{"class":348,"line":585},[346,2645,554],{"class":356},[346,2647,484],{"class":383},[346,2649,420],{"class":356},[346,2651,384],{"class":383},[346,2653,570],{"class":387},[346,2655,492],{"class":491},[346,2657,963],{"class":356},[346,2659,384],{"class":383},[346,2661,1569],{"class":623},[346,2663,603],{"class":383},[346,2665,858],{"class":623},[346,2667,766],{"class":383},[346,2669,2670],{"class":348,"line":590},[346,2671,2672],{"class":529},"    # After @L.config, the activation field default is '${activation}'.\n",[346,2674,2675],{"class":348,"line":596},[346,2676,2677],{"class":529},"    # Pyright sees: nn.Module  (lie — matches the Group element type)\n",[346,2679,2680],{"class":348,"line":635},[346,2681,364],{"emptyLinePlaceholder":363},[346,2683,2684],{"class":348,"line":640},[346,2685,2420],{"class":529},[346,2687,2688],{"class":348,"line":646},[346,2689,2690],{"class":529},"# Step 3 — Expose the schema as a module-level name\n",[346,2692,2693],{"class":348,"line":654},[346,2694,2420],{"class":529},[346,2696,2697],{"class":348,"line":675},[346,2698,2699],{"class":529},"# When laco.load() reads this file, 'schema' is exposed as a fragment:\n",[346,2701,2702],{"class":348,"line":691},[346,2703,2704],{"class":529},"#   laco.load('configs:\u002F\u002Fexamples\u002Ftyped\u002Fmlp.py#schema')\n",[346,2706,2707,2710,2712],{"class":348,"line":749},[346,2708,2709],{"class":356},"schema ",[346,2711,960],{"class":491},[346,2713,2714],{"class":356}," MLPSchema\n",[337,2716,2718],{"className":339,"code":2717,"language":341,"meta":342,"style":342},"# ------------------------------------------------------------------\n# Step 4 — Declare the defaults list\n# ------------------------------------------------------------------\ndefaults = L.Defaults(\n    L.self_,                                            # include this config's own fields\n    L.bind(MLPSchema.activation, ActivationGroup.relu), # default activation = relu\n)\n# Serialises to: [\"_self_\", {\"activationgroup\": \"relu\"}]\nprint(\"defaults:\", defaults)\n",[224,2719,2720,2724,2729,2733,2747,2760,2789,2793,2798],{"__ignoreMap":342},[346,2721,2722],{"class":348,"line":349},[346,2723,2420],{"class":529},[346,2725,2726],{"class":348,"line":360},[346,2727,2728],{"class":529},"# Step 4 — Declare the defaults list\n",[346,2730,2731],{"class":348,"line":367},[346,2732,2420],{"class":529},[346,2734,2735,2737,2739,2741,2743,2745],{"class":348,"line":375},[346,2736,1890],{"class":356},[346,2738,960],{"class":491},[346,2740,963],{"class":356},[346,2742,384],{"class":383},[346,2744,1899],{"class":623},[346,2746,1902],{"class":383},[346,2748,2749,2751,2753,2755,2757],{"class":348,"line":396},[346,2750,1907],{"class":623},[346,2752,384],{"class":383},[346,2754,1912],{"class":387},[346,2756,423],{"class":383},[346,2758,2759],{"class":529},"                                            # include this config's own fields\n",[346,2761,2762,2764,2766,2768,2770,2772,2774,2776,2778,2780,2782,2784,2786],{"class":348,"line":410},[346,2763,1907],{"class":623},[346,2765,384],{"class":383},[346,2767,1926],{"class":623},[346,2769,603],{"class":383},[346,2771,1613],{"class":623},[346,2773,384],{"class":383},[346,2775,629],{"class":387},[346,2777,423],{"class":383},[346,2779,915],{"class":623},[346,2781,384],{"class":383},[346,2783,1124],{"class":387},[346,2785,1945],{"class":383},[346,2787,2788],{"class":529}," # default activation = relu\n",[346,2790,2791],{"class":348,"line":533},[346,2792,766],{"class":383},[346,2794,2795],{"class":348,"line":539},[346,2796,2797],{"class":529},"# Serialises to: [\"_self_\", {\"activationgroup\": \"relu\"}]\n",[346,2799,2800,2802,2804,2806,2808,2810,2812,2814],{"class":348,"line":545},[346,2801,600],{"class":599},[346,2803,603],{"class":383},[346,2805,607],{"class":606},[346,2807,1967],{"class":610},[346,2809,607],{"class":606},[346,2811,423],{"class":383},[346,2813,1974],{"class":623},[346,2815,766],{"class":383},[784,2817],{"data":1979,"kind":787},[337,2819,2821],{"className":339,"code":2820,"language":341,"meta":342,"style":342},"# ------------------------------------------------------------------\n# Step 5 — Build the model config using L.chosen and L.ref\n# ------------------------------------------------------------------\nmodel = L.call(nn.Sequential, root=True)(\n    L.OrderedDict(\n        (\n            \"input\",\n            L.call(nn.Sequential)(\n                L.call(nn.Linear)(\n                    in_features=L.ref(\"${schema.dim_in}\"),\n                    out_features=L.ref(\"${schema.dim_hidden}\"),\n                ),\n                L.chosen(ActivationGroup),   # \u003C-- resolves to selected activation\n            ),\n        ),\n        (\n            \"hidden\",\n            L.call(nn.Sequential, expand_args=True)(\n                L.repeat(\n                    L.ref(\"${schema.num_layers}\"),\n                    L.call(nn.Sequential)(\n                        L.call(nn.Linear)(\n                            in_features=L.ref(\"${schema.dim_hidden}\"),\n                            out_features=L.ref(\"${schema.dim_hidden}\"),\n                        ),\n                        L.chosen(ActivationGroup),  # same interpolation — stays in sync\n                    ),\n                ),\n            ),\n        ),\n        (\n            \"output\",\n            L.call(nn.Sequential)(\n                L.call(nn.Linear)(\n                    in_features=L.ref(\"${schema.dim_hidden}\"),\n                    out_features=L.ref(\"${schema.dim_out}\"),\n                )\n            ),\n        ),\n    )\n)\n\nprint(\"model type (runtime):\", type(model))\n",[224,2822,2823,2827,2832,2836,2872,2883,2888,2901,2920,2940,2969,2995,3000,3017,3022,3027,3031,3042,3069,3080,3102,3120,3140,3166,3192,3198,3216,3222,3227,3232,3237,3242,3254,3273,3292,3317,3343,3349,3354,3359,3365,3370,3375],{"__ignoreMap":342},[346,2824,2825],{"class":348,"line":349},[346,2826,2420],{"class":529},[346,2828,2829],{"class":348,"line":360},[346,2830,2831],{"class":529},"# Step 5 — Build the model config using L.chosen and L.ref\n",[346,2833,2834],{"class":348,"line":367},[346,2835,2420],{"class":529},[346,2837,2838,2841,2843,2845,2847,2849,2851,2853,2855,2858,2860,2863,2865,2869],{"class":348,"line":375},[346,2839,2840],{"class":356},"model ",[346,2842,960],{"class":491},[346,2844,963],{"class":356},[346,2846,384],{"class":383},[346,2848,968],{"class":623},[346,2850,603],{"class":383},[346,2852,565],{"class":623},[346,2854,384],{"class":383},[346,2856,2857],{"class":387},"Sequential",[346,2859,423],{"class":383},[346,2861,2862],{"class":2129}," root",[346,2864,960],{"class":491},[346,2866,2868],{"class":2867},"s39Yj","True",[346,2870,2871],{"class":383},")(\n",[346,2873,2874,2876,2878,2881],{"class":348,"line":396},[346,2875,1907],{"class":623},[346,2877,384],{"class":383},[346,2879,2880],{"class":623},"OrderedDict",[346,2882,1902],{"class":383},[346,2884,2885],{"class":348,"line":410},[346,2886,2887],{"class":383},"        (\n",[346,2889,2890,2893,2896,2898],{"class":348,"line":533},[346,2891,2892],{"class":606},"            \"",[346,2894,2895],{"class":610},"input",[346,2897,607],{"class":606},[346,2899,2900],{"class":383},",\n",[346,2902,2903,2906,2908,2910,2912,2914,2916,2918],{"class":348,"line":539},[346,2904,2905],{"class":623},"            L",[346,2907,384],{"class":383},[346,2909,968],{"class":623},[346,2911,603],{"class":383},[346,2913,565],{"class":623},[346,2915,384],{"class":383},[346,2917,2857],{"class":387},[346,2919,2871],{"class":383},[346,2921,2922,2925,2927,2929,2931,2933,2935,2938],{"class":348,"line":545},[346,2923,2924],{"class":623},"                L",[346,2926,384],{"class":383},[346,2928,968],{"class":623},[346,2930,603],{"class":383},[346,2932,565],{"class":623},[346,2934,384],{"class":383},[346,2936,2937],{"class":387},"Linear",[346,2939,2871],{"class":383},[346,2941,2942,2945,2947,2949,2951,2954,2956,2958,2961,2964,2966],{"class":348,"line":551},[346,2943,2944],{"class":2129},"                    in_features",[346,2946,960],{"class":491},[346,2948,458],{"class":623},[346,2950,384],{"class":383},[346,2952,2953],{"class":623},"ref",[346,2955,603],{"class":383},[346,2957,607],{"class":606},[346,2959,2960],{"class":610},"$",[346,2962,2963],{"class":495},"{schema.dim_in}",[346,2965,607],{"class":606},[346,2967,2968],{"class":383},"),\n",[346,2970,2971,2974,2976,2978,2980,2982,2984,2986,2988,2991,2993],{"class":348,"line":585},[346,2972,2973],{"class":2129},"                    out_features",[346,2975,960],{"class":491},[346,2977,458],{"class":623},[346,2979,384],{"class":383},[346,2981,2953],{"class":623},[346,2983,603],{"class":383},[346,2985,607],{"class":606},[346,2987,2960],{"class":610},[346,2989,2990],{"class":495},"{schema.dim_hidden}",[346,2992,607],{"class":606},[346,2994,2968],{"class":383},[346,2996,2997],{"class":348,"line":590},[346,2998,2999],{"class":383},"                ),\n",[346,3001,3002,3004,3006,3008,3010,3012,3014],{"class":348,"line":596},[346,3003,2924],{"class":623},[346,3005,384],{"class":383},[346,3007,2304],{"class":623},[346,3009,603],{"class":383},[346,3011,858],{"class":623},[346,3013,1945],{"class":383},[346,3015,3016],{"class":529},"   # \u003C-- resolves to selected activation\n",[346,3018,3019],{"class":348,"line":635},[346,3020,3021],{"class":383},"            ),\n",[346,3023,3024],{"class":348,"line":640},[346,3025,3026],{"class":383},"        ),\n",[346,3028,3029],{"class":348,"line":646},[346,3030,2887],{"class":383},[346,3032,3033,3035,3038,3040],{"class":348,"line":654},[346,3034,2892],{"class":606},[346,3036,3037],{"class":610},"hidden",[346,3039,607],{"class":606},[346,3041,2900],{"class":383},[346,3043,3044,3046,3048,3050,3052,3054,3056,3058,3060,3063,3065,3067],{"class":348,"line":675},[346,3045,2905],{"class":623},[346,3047,384],{"class":383},[346,3049,968],{"class":623},[346,3051,603],{"class":383},[346,3053,565],{"class":623},[346,3055,384],{"class":383},[346,3057,2857],{"class":387},[346,3059,423],{"class":383},[346,3061,3062],{"class":2129}," expand_args",[346,3064,960],{"class":491},[346,3066,2868],{"class":2867},[346,3068,2871],{"class":383},[346,3070,3071,3073,3075,3078],{"class":348,"line":691},[346,3072,2924],{"class":623},[346,3074,384],{"class":383},[346,3076,3077],{"class":623},"repeat",[346,3079,1902],{"class":383},[346,3081,3082,3085,3087,3089,3091,3093,3095,3098,3100],{"class":348,"line":749},[346,3083,3084],{"class":623},"                    L",[346,3086,384],{"class":383},[346,3088,2953],{"class":623},[346,3090,603],{"class":383},[346,3092,607],{"class":606},[346,3094,2960],{"class":610},[346,3096,3097],{"class":495},"{schema.num_layers}",[346,3099,607],{"class":606},[346,3101,2968],{"class":383},[346,3103,3104,3106,3108,3110,3112,3114,3116,3118],{"class":348,"line":769},[346,3105,3084],{"class":623},[346,3107,384],{"class":383},[346,3109,968],{"class":623},[346,3111,603],{"class":383},[346,3113,565],{"class":623},[346,3115,384],{"class":383},[346,3117,2857],{"class":387},[346,3119,2871],{"class":383},[346,3121,3123,3126,3128,3130,3132,3134,3136,3138],{"class":348,"line":3122},22,[346,3124,3125],{"class":623},"                        L",[346,3127,384],{"class":383},[346,3129,968],{"class":623},[346,3131,603],{"class":383},[346,3133,565],{"class":623},[346,3135,384],{"class":383},[346,3137,2937],{"class":387},[346,3139,2871],{"class":383},[346,3141,3143,3146,3148,3150,3152,3154,3156,3158,3160,3162,3164],{"class":348,"line":3142},23,[346,3144,3145],{"class":2129},"                            in_features",[346,3147,960],{"class":491},[346,3149,458],{"class":623},[346,3151,384],{"class":383},[346,3153,2953],{"class":623},[346,3155,603],{"class":383},[346,3157,607],{"class":606},[346,3159,2960],{"class":610},[346,3161,2990],{"class":495},[346,3163,607],{"class":606},[346,3165,2968],{"class":383},[346,3167,3169,3172,3174,3176,3178,3180,3182,3184,3186,3188,3190],{"class":348,"line":3168},24,[346,3170,3171],{"class":2129},"                            out_features",[346,3173,960],{"class":491},[346,3175,458],{"class":623},[346,3177,384],{"class":383},[346,3179,2953],{"class":623},[346,3181,603],{"class":383},[346,3183,607],{"class":606},[346,3185,2960],{"class":610},[346,3187,2990],{"class":495},[346,3189,607],{"class":606},[346,3191,2968],{"class":383},[346,3193,3195],{"class":348,"line":3194},25,[346,3196,3197],{"class":383},"                        ),\n",[346,3199,3201,3203,3205,3207,3209,3211,3213],{"class":348,"line":3200},26,[346,3202,3125],{"class":623},[346,3204,384],{"class":383},[346,3206,2304],{"class":623},[346,3208,603],{"class":383},[346,3210,858],{"class":623},[346,3212,1945],{"class":383},[346,3214,3215],{"class":529},"  # same interpolation — stays in sync\n",[346,3217,3219],{"class":348,"line":3218},27,[346,3220,3221],{"class":383},"                    ),\n",[346,3223,3225],{"class":348,"line":3224},28,[346,3226,2999],{"class":383},[346,3228,3230],{"class":348,"line":3229},29,[346,3231,3021],{"class":383},[346,3233,3235],{"class":348,"line":3234},30,[346,3236,3026],{"class":383},[346,3238,3240],{"class":348,"line":3239},31,[346,3241,2887],{"class":383},[346,3243,3245,3247,3250,3252],{"class":348,"line":3244},32,[346,3246,2892],{"class":606},[346,3248,3249],{"class":610},"output",[346,3251,607],{"class":606},[346,3253,2900],{"class":383},[346,3255,3257,3259,3261,3263,3265,3267,3269,3271],{"class":348,"line":3256},33,[346,3258,2905],{"class":623},[346,3260,384],{"class":383},[346,3262,968],{"class":623},[346,3264,603],{"class":383},[346,3266,565],{"class":623},[346,3268,384],{"class":383},[346,3270,2857],{"class":387},[346,3272,2871],{"class":383},[346,3274,3276,3278,3280,3282,3284,3286,3288,3290],{"class":348,"line":3275},34,[346,3277,2924],{"class":623},[346,3279,384],{"class":383},[346,3281,968],{"class":623},[346,3283,603],{"class":383},[346,3285,565],{"class":623},[346,3287,384],{"class":383},[346,3289,2937],{"class":387},[346,3291,2871],{"class":383},[346,3293,3295,3297,3299,3301,3303,3305,3307,3309,3311,3313,3315],{"class":348,"line":3294},35,[346,3296,2944],{"class":2129},[346,3298,960],{"class":491},[346,3300,458],{"class":623},[346,3302,384],{"class":383},[346,3304,2953],{"class":623},[346,3306,603],{"class":383},[346,3308,607],{"class":606},[346,3310,2960],{"class":610},[346,3312,2990],{"class":495},[346,3314,607],{"class":606},[346,3316,2968],{"class":383},[346,3318,3320,3322,3324,3326,3328,3330,3332,3334,3336,3339,3341],{"class":348,"line":3319},36,[346,3321,2973],{"class":2129},[346,3323,960],{"class":491},[346,3325,458],{"class":623},[346,3327,384],{"class":383},[346,3329,2953],{"class":623},[346,3331,603],{"class":383},[346,3333,607],{"class":606},[346,3335,2960],{"class":610},[346,3337,3338],{"class":495},"{schema.dim_out}",[346,3340,607],{"class":606},[346,3342,2968],{"class":383},[346,3344,3346],{"class":348,"line":3345},37,[346,3347,3348],{"class":383},"                )\n",[346,3350,3352],{"class":348,"line":3351},38,[346,3353,3021],{"class":383},[346,3355,3357],{"class":348,"line":3356},39,[346,3358,3026],{"class":383},[346,3360,3362],{"class":348,"line":3361},40,[346,3363,3364],{"class":383},"    )\n",[346,3366,3368],{"class":348,"line":3367},41,[346,3369,766],{"class":383},[346,3371,3373],{"class":348,"line":3372},42,[346,3374,364],{"emptyLinePlaceholder":363},[346,3376,3378,3380,3382,3384,3387,3389,3391,3393,3395,3398],{"class":348,"line":3377},43,[346,3379,600],{"class":599},[346,3381,603],{"class":383},[346,3383,607],{"class":606},[346,3385,3386],{"class":610},"model type (runtime):",[346,3388,607],{"class":606},[346,3390,423],{"class":383},[346,3392,559],{"class":487},[346,3394,603],{"class":383},[346,3396,3397],{"class":623},"model",[346,3399,632],{"class":383},[784,3401],{"data":3402,"kind":787},"bW9kZWwgdHlwZSAocnVudGltZSk6IDxjbGFzcyAnb21lZ2Fjb25mLmRpY3Rjb25maWcuRGljdENvbmZpZyc+Cg==",[337,3404,3406],{"className":339,"code":3405,"language":341,"meta":342,"style":342},"# The example at sources\u002Flaco\u002Fexamples\u002Ftyped\u002Fmlp.py declares the group, schema,\n# defaults list, and model body. To load + compose it here we materialise the\n# same wiring to a small file (the defaults list selects the activation entry,\n# and L.chosen \u002F L.slot share the \"activation\" package so the interpolation\n# resolves). This mirrors the source file with the group binding made explicit.\nimport tempfile, textwrap, pathlib\n\n_MLP_TYPED = textwrap.dedent(\"\"\"\n    import laco.language as L\n    from torch import nn\n\n    class ActivationGroup(L.Group[nn.Module]):\n        relu = L.call(nn.ReLU)()\n        gelu = L.call(nn.GELU)()\n        silu = L.call(nn.SiLU)()\n\n    @L.config\n    class MLPSchema:\n        dim_in:     int       = 128\n        dim_out:    int       = 128\n        dim_hidden: int       = 256\n        num_layers: int       = 3\n        activation: nn.Module = L.slot(ActivationGroup)   # -> '${activation}'\n\n    schema = MLPSchema\n\n    # The defaults list selects the default entry for the group. L.bind composes\n    # ActivationGroup.relu under the slot's package ('activation').\n    defaults = L.Defaults(\n        L.self_,\n        L.bind(MLPSchema.activation, ActivationGroup.relu),\n    )\n\n    model = L.call(nn.Sequential, root=True)(\n        L.OrderedDict(\n            (\"input\", L.call(nn.Sequential)(\n                L.call(nn.Linear)(\n                    in_features=L.ref(\"${schema.dim_in}\"),\n                    out_features=L.ref(\"${schema.dim_hidden}\"),\n                ),\n                L.chosen(ActivationGroup, package=\"activation\"),\n            )),\n            (\"hidden\", L.call(nn.Sequential, expand_args=True)(\n                L.repeat(\n                    L.ref(\"${schema.num_layers}\"),\n                    L.call(nn.Sequential)(\n                        L.call(nn.Linear)(\n                            in_features=L.ref(\"${schema.dim_hidden}\"),\n                            out_features=L.ref(\"${schema.dim_hidden}\"),\n                        ),\n                        L.chosen(ActivationGroup, package=\"activation\"),\n                    ),\n                ),\n            )),\n            (\"output\", L.call(nn.Sequential)(\n                L.call(nn.Linear)(\n                    in_features=L.ref(\"${schema.dim_hidden}\"),\n                    out_features=L.ref(\"${schema.dim_out}\"),\n                )\n            )),\n        )\n    )\n\n    __all__ = [\"model\", \"schema\", \"defaults\"]\n\"\"\")\n\n_mlp_path = pathlib.Path(tempfile.mkdtemp()) \u002F \"mlp.py\"\n_mlp_path.write_text(_MLP_TYPED)\n\n# Inspect the schema fragment (the typed dataclass node).\nschema_cfg = laco.load(f\"{_mlp_path}#schema\")\nprint(\"--- schema fragment ---\")\nprint(laco.dump(schema_cfg))\n\n",[224,3407,3408,3413,3418,3423,3428,3433,3450,3454,3472,3477,3482,3486,3491,3496,3501,3506,3510,3515,3520,3525,3530,3535,3540,3551,3555,3560,3564,3569,3574,3579,3584,3589,3593,3597,3602,3607,3612,3617,3627,3636,3640,3645,3650,3655,3661,3671,3677,3683,3693,3703,3708,3714,3719,3724,3729,3735,3740,3749,3758,3763,3768,3774,3779,3784,3790,3798,3803,3843,3860,3865,3871,3903,3919],{"__ignoreMap":342},[346,3409,3410],{"class":348,"line":349},[346,3411,3412],{"class":529},"# The example at sources\u002Flaco\u002Fexamples\u002Ftyped\u002Fmlp.py declares the group, schema,\n",[346,3414,3415],{"class":348,"line":360},[346,3416,3417],{"class":529},"# defaults list, and model body. To load + compose it here we materialise the\n",[346,3419,3420],{"class":348,"line":367},[346,3421,3422],{"class":529},"# same wiring to a small file (the defaults list selects the activation entry,\n",[346,3424,3425],{"class":348,"line":375},[346,3426,3427],{"class":529},"# and L.chosen \u002F L.slot share the \"activation\" package so the interpolation\n",[346,3429,3430],{"class":348,"line":396},[346,3431,3432],{"class":529},"# resolves). This mirrors the source file with the group binding made explicit.\n",[346,3434,3435,3437,3440,3442,3445,3447],{"class":348,"line":410},[346,3436,353],{"class":352},[346,3438,3439],{"class":356}," tempfile",[346,3441,423],{"class":383},[346,3443,3444],{"class":356}," textwrap",[346,3446,423],{"class":383},[346,3448,3449],{"class":356}," pathlib\n",[346,3451,3452],{"class":348,"line":533},[346,3453,364],{"emptyLinePlaceholder":363},[346,3455,3456,3459,3461,3463,3465,3468,3470],{"class":348,"line":539},[346,3457,3458],{"class":717},"_MLP_TYPED",[346,3460,492],{"class":491},[346,3462,3444],{"class":356},[346,3464,384],{"class":383},[346,3466,3467],{"class":623},"dedent",[346,3469,603],{"class":383},[346,3471,948],{"class":606},[346,3473,3474],{"class":348,"line":545},[346,3475,3476],{"class":610},"    import laco.language as L\n",[346,3478,3479],{"class":348,"line":551},[346,3480,3481],{"class":610},"    from torch import nn\n",[346,3483,3484],{"class":348,"line":585},[346,3485,364],{"emptyLinePlaceholder":363},[346,3487,3488],{"class":348,"line":590},[346,3489,3490],{"class":610},"    class ActivationGroup(L.Group[nn.Module]):\n",[346,3492,3493],{"class":348,"line":596},[346,3494,3495],{"class":610},"        relu = L.call(nn.ReLU)()\n",[346,3497,3498],{"class":348,"line":635},[346,3499,3500],{"class":610},"        gelu = L.call(nn.GELU)()\n",[346,3502,3503],{"class":348,"line":640},[346,3504,3505],{"class":610},"        silu = L.call(nn.SiLU)()\n",[346,3507,3508],{"class":348,"line":646},[346,3509,364],{"emptyLinePlaceholder":363},[346,3511,3512],{"class":348,"line":654},[346,3513,3514],{"class":610},"    @L.config\n",[346,3516,3517],{"class":348,"line":675},[346,3518,3519],{"class":610},"    class MLPSchema:\n",[346,3521,3522],{"class":348,"line":691},[346,3523,3524],{"class":610},"        dim_in:     int       = 128\n",[346,3526,3527],{"class":348,"line":749},[346,3528,3529],{"class":610},"        dim_out:    int       = 128\n",[346,3531,3532],{"class":348,"line":769},[346,3533,3534],{"class":610},"        dim_hidden: int       = 256\n",[346,3536,3537],{"class":348,"line":3122},[346,3538,3539],{"class":610},"        num_layers: int       = 3\n",[346,3541,3542,3545,3548],{"class":348,"line":3142},[346,3543,3544],{"class":610},"        activation: nn.Module = L.slot(ActivationGroup)   # -> '$",[346,3546,3547],{"class":495},"{activation}",[346,3549,3550],{"class":610},"'\n",[346,3552,3553],{"class":348,"line":3168},[346,3554,364],{"emptyLinePlaceholder":363},[346,3556,3557],{"class":348,"line":3194},[346,3558,3559],{"class":610},"    schema = MLPSchema\n",[346,3561,3562],{"class":348,"line":3200},[346,3563,364],{"emptyLinePlaceholder":363},[346,3565,3566],{"class":348,"line":3218},[346,3567,3568],{"class":610},"    # The defaults list selects the default entry for the group. L.bind composes\n",[346,3570,3571],{"class":348,"line":3224},[346,3572,3573],{"class":610},"    # ActivationGroup.relu under the slot's package ('activation').\n",[346,3575,3576],{"class":348,"line":3229},[346,3577,3578],{"class":610},"    defaults = L.Defaults(\n",[346,3580,3581],{"class":348,"line":3234},[346,3582,3583],{"class":610},"        L.self_,\n",[346,3585,3586],{"class":348,"line":3239},[346,3587,3588],{"class":610},"        L.bind(MLPSchema.activation, ActivationGroup.relu),\n",[346,3590,3591],{"class":348,"line":3244},[346,3592,3364],{"class":610},[346,3594,3595],{"class":348,"line":3256},[346,3596,364],{"emptyLinePlaceholder":363},[346,3598,3599],{"class":348,"line":3275},[346,3600,3601],{"class":610},"    model = L.call(nn.Sequential, root=True)(\n",[346,3603,3604],{"class":348,"line":3294},[346,3605,3606],{"class":610},"        L.OrderedDict(\n",[346,3608,3609],{"class":348,"line":3319},[346,3610,3611],{"class":610},"            (\"input\", L.call(nn.Sequential)(\n",[346,3613,3614],{"class":348,"line":3345},[346,3615,3616],{"class":610},"                L.call(nn.Linear)(\n",[346,3618,3619,3622,3624],{"class":348,"line":3351},[346,3620,3621],{"class":610},"                    in_features=L.ref(\"$",[346,3623,2963],{"class":495},[346,3625,3626],{"class":610},"\"),\n",[346,3628,3629,3632,3634],{"class":348,"line":3356},[346,3630,3631],{"class":610},"                    out_features=L.ref(\"$",[346,3633,2990],{"class":495},[346,3635,3626],{"class":610},[346,3637,3638],{"class":348,"line":3361},[346,3639,2999],{"class":610},[346,3641,3642],{"class":348,"line":3367},[346,3643,3644],{"class":610},"                L.chosen(ActivationGroup, package=\"activation\"),\n",[346,3646,3647],{"class":348,"line":3372},[346,3648,3649],{"class":610},"            )),\n",[346,3651,3652],{"class":348,"line":3377},[346,3653,3654],{"class":610},"            (\"hidden\", L.call(nn.Sequential, expand_args=True)(\n",[346,3656,3658],{"class":348,"line":3657},44,[346,3659,3660],{"class":610},"                L.repeat(\n",[346,3662,3664,3667,3669],{"class":348,"line":3663},45,[346,3665,3666],{"class":610},"                    L.ref(\"$",[346,3668,3097],{"class":495},[346,3670,3626],{"class":610},[346,3672,3674],{"class":348,"line":3673},46,[346,3675,3676],{"class":610},"                    L.call(nn.Sequential)(\n",[346,3678,3680],{"class":348,"line":3679},47,[346,3681,3682],{"class":610},"                        L.call(nn.Linear)(\n",[346,3684,3686,3689,3691],{"class":348,"line":3685},48,[346,3687,3688],{"class":610},"                            in_features=L.ref(\"$",[346,3690,2990],{"class":495},[346,3692,3626],{"class":610},[346,3694,3696,3699,3701],{"class":348,"line":3695},49,[346,3697,3698],{"class":610},"                            out_features=L.ref(\"$",[346,3700,2990],{"class":495},[346,3702,3626],{"class":610},[346,3704,3706],{"class":348,"line":3705},50,[346,3707,3197],{"class":610},[346,3709,3711],{"class":348,"line":3710},51,[346,3712,3713],{"class":610},"                        L.chosen(ActivationGroup, package=\"activation\"),\n",[346,3715,3717],{"class":348,"line":3716},52,[346,3718,3221],{"class":610},[346,3720,3722],{"class":348,"line":3721},53,[346,3723,2999],{"class":610},[346,3725,3727],{"class":348,"line":3726},54,[346,3728,3649],{"class":610},[346,3730,3732],{"class":348,"line":3731},55,[346,3733,3734],{"class":610},"            (\"output\", L.call(nn.Sequential)(\n",[346,3736,3738],{"class":348,"line":3737},56,[346,3739,3616],{"class":610},[346,3741,3743,3745,3747],{"class":348,"line":3742},57,[346,3744,3621],{"class":610},[346,3746,2990],{"class":495},[346,3748,3626],{"class":610},[346,3750,3752,3754,3756],{"class":348,"line":3751},58,[346,3753,3631],{"class":610},[346,3755,3338],{"class":495},[346,3757,3626],{"class":610},[346,3759,3761],{"class":348,"line":3760},59,[346,3762,3348],{"class":610},[346,3764,3766],{"class":348,"line":3765},60,[346,3767,3649],{"class":610},[346,3769,3771],{"class":348,"line":3770},61,[346,3772,3773],{"class":610},"        )\n",[346,3775,3777],{"class":348,"line":3776},62,[346,3778,3364],{"class":610},[346,3780,3782],{"class":348,"line":3781},63,[346,3783,364],{"emptyLinePlaceholder":363},[346,3785,3787],{"class":348,"line":3786},64,[346,3788,3789],{"class":610},"    __all__ = [\"model\", \"schema\", \"defaults\"]\n",[346,3791,3793,3796],{"class":348,"line":3792},65,[346,3794,3795],{"class":606},"\"\"\"",[346,3797,766],{"class":383},[346,3799,3801],{"class":348,"line":3800},66,[346,3802,364],{"emptyLinePlaceholder":363},[346,3804,3806,3809,3811,3814,3816,3819,3821,3824,3826,3829,3831,3834,3837,3840],{"class":348,"line":3805},67,[346,3807,3808],{"class":356},"_mlp_path ",[346,3810,960],{"class":491},[346,3812,3813],{"class":356}," pathlib",[346,3815,384],{"class":383},[346,3817,3818],{"class":623},"Path",[346,3820,603],{"class":383},[346,3822,3823],{"class":623},"tempfile",[346,3825,384],{"class":383},[346,3827,3828],{"class":623},"mkdtemp",[346,3830,669],{"class":383},[346,3832,3833],{"class":491}," \u002F",[346,3835,3836],{"class":606}," \"",[346,3838,3839],{"class":610},"mlp.py",[346,3841,3842],{"class":606},"\"\n",[346,3844,3846,3849,3851,3854,3856,3858],{"class":348,"line":3845},68,[346,3847,3848],{"class":356},"_mlp_path",[346,3850,384],{"class":383},[346,3852,3853],{"class":623},"write_text",[346,3855,603],{"class":383},[346,3857,3458],{"class":599},[346,3859,766],{"class":383},[346,3861,3863],{"class":348,"line":3862},69,[346,3864,364],{"emptyLinePlaceholder":363},[346,3866,3868],{"class":348,"line":3867},70,[346,3869,3870],{"class":529},"# Inspect the schema fragment (the typed dataclass node).\n",[346,3872,3874,3877,3879,3881,3883,3886,3888,3890,3892,3894,3896,3898,3901],{"class":348,"line":3873},71,[346,3875,3876],{"class":356},"schema_cfg ",[346,3878,960],{"class":491},[346,3880,380],{"class":356},[346,3882,384],{"class":383},[346,3884,3885],{"class":623},"load",[346,3887,603],{"class":383},[346,3889,699],{"class":468},[346,3891,607],{"class":610},[346,3893,704],{"class":495},[346,3895,3848],{"class":623},[346,3897,721],{"class":495},[346,3899,3900],{"class":610},"#schema\"",[346,3902,766],{"class":383},[346,3904,3906,3908,3910,3912,3915,3917],{"class":348,"line":3905},72,[346,3907,600],{"class":599},[346,3909,603],{"class":383},[346,3911,607],{"class":606},[346,3913,3914],{"class":610},"--- schema fragment ---",[346,3916,607],{"class":606},[346,3918,766],{"class":383},[346,3920,3922,3924,3926,3928,3930,3932,3934,3937],{"class":348,"line":3921},73,[346,3923,600],{"class":599},[346,3925,603],{"class":383},[346,3927,1161],{"class":623},[346,3929,384],{"class":383},[346,3931,1166],{"class":623},[346,3933,603],{"class":383},[346,3935,3936],{"class":623},"schema_cfg",[346,3938,632],{"class":383},[784,3940],{"data":3941,"kind":787},"LS0tIHNjaGVtYSBmcmFnbWVudCAtLS0KISFweXRob24vb2JqZWN0OmJ1aWx0aW5zLk1MUFNjaGVtYQphY3RpdmF0aW9uOiB7X2NvbnZlcnRfOiBhbGwsIF90YXJnZXRfOiB0b3JjaC5ubi5SZUxVfQpkaW1faGlkZGVuOiAyNTYKZGltX2luOiAxMjgKZGltX291dDogMTI4Cm51bV9sYXllcnM6IDMKCg==",[337,3943,3945],{"className":339,"code":3944,"language":341,"meta":342,"style":342},"# Load the full config (so the model body can resolve cross-references into\n# `schema`) and show the composed activation node — the defaults list selected\n# `relu`, which L.chosen pulled into every layer.\ncfg = laco.load(str(_mlp_path))\nprint(\"--- composed activation (default: relu) ---\")\nprint(laco.dump(cfg.activation))\nprint(\"--- instantiated input block (note the resolved ${activation} -> ReLU) ---\")\nprint(laco.instantiate(cfg.model).input)\n\n",[224,3946,3947,3952,3957,3962,3985,4000,4023,4043],{"__ignoreMap":342},[346,3948,3949],{"class":348,"line":349},[346,3950,3951],{"class":529},"# Load the full config (so the model body can resolve cross-references into\n",[346,3953,3954],{"class":348,"line":360},[346,3955,3956],{"class":529},"# `schema`) and show the composed activation node — the defaults list selected\n",[346,3958,3959],{"class":348,"line":367},[346,3960,3961],{"class":529},"# `relu`, which L.chosen pulled into every layer.\n",[346,3963,3964,3967,3969,3971,3973,3975,3977,3979,3981,3983],{"class":348,"line":375},[346,3965,3966],{"class":356},"cfg ",[346,3968,960],{"class":491},[346,3970,380],{"class":356},[346,3972,384],{"class":383},[346,3974,3885],{"class":623},[346,3976,603],{"class":383},[346,3978,1761],{"class":487},[346,3980,603],{"class":383},[346,3982,3848],{"class":623},[346,3984,632],{"class":383},[346,3986,3987,3989,3991,3993,3996,3998],{"class":348,"line":396},[346,3988,600],{"class":599},[346,3990,603],{"class":383},[346,3992,607],{"class":606},[346,3994,3995],{"class":610},"--- composed activation (default: relu) ---",[346,3997,607],{"class":606},[346,3999,766],{"class":383},[346,4001,4002,4004,4006,4008,4010,4012,4014,4017,4019,4021],{"class":348,"line":410},[346,4003,600],{"class":599},[346,4005,603],{"class":383},[346,4007,1161],{"class":623},[346,4009,384],{"class":383},[346,4011,1166],{"class":623},[346,4013,603],{"class":383},[346,4015,4016],{"class":623},"cfg",[346,4018,384],{"class":383},[346,4020,629],{"class":387},[346,4022,632],{"class":383},[346,4024,4025,4027,4029,4031,4034,4036,4039,4041],{"class":348,"line":533},[346,4026,600],{"class":599},[346,4028,603],{"class":383},[346,4030,607],{"class":606},[346,4032,4033],{"class":610},"--- instantiated input block (note the resolved $",[346,4035,3547],{"class":495},[346,4037,4038],{"class":610}," -> ReLU) ---",[346,4040,607],{"class":606},[346,4042,766],{"class":383},[346,4044,4045,4047,4049,4051,4053,4056,4058,4060,4062,4064,4066,4068],{"class":348,"line":539},[346,4046,600],{"class":599},[346,4048,603],{"class":383},[346,4050,1161],{"class":623},[346,4052,384],{"class":383},[346,4054,4055],{"class":623},"instantiate",[346,4057,603],{"class":383},[346,4059,4016],{"class":623},[346,4061,384],{"class":383},[346,4063,3397],{"class":387},[346,4065,239],{"class":383},[346,4067,2895],{"class":387},[346,4069,766],{"class":383},[784,4071],{"data":4072,"kind":787},"LS0tIGNvbXBvc2VkIGFjdGl2YXRpb24gKGRlZmF1bHQ6IHJlbHUpIC0tLQp7X2NvbnZlcnRfOiBhbGwsIF9sYWNvXzogMSwgX3RhcmdldF86IHRvcmNoLm5uLlJlTFV9CgotLS0gaW5zdGFudGlhdGVkIGlucHV0IGJsb2NrIChub3RlIHRoZSByZXNvbHZlZCAke2FjdGl2YXRpb259IC0+IFJlTFUpIC0tLQpTZXF1ZW50aWFsKAogICgwKTogTGluZWFyKGluX2ZlYXR1cmVzPTEyOCwgb3V0X2ZlYXR1cmVzPTI1NiwgYmlhcz1UcnVlKQogICgxKTogUmVMVSgpCikK",[428,4074],{},[431,4076,4078],{"id":4077},"section-7-overriding-a-group-selection","Section 7: Overriding a Group Selection",[216,4080,4081,4082,4084],{},"The real payoff: swapping the activation is a single CLI-style override. The model\nconfig body is never touched: ",[224,4083,2284],{}," resolves to whatever\nthe defaults list selected.",[337,4086,4088],{"className":339,"code":4087,"language":341,"meta":342,"style":342},"# Default selection: relu\ncfg_relu = laco.load(str(_mlp_path))\nprint(\"=== relu (default) ===\")\nprint(laco.dump(cfg_relu.activation))\n\n",[224,4089,4090,4095,4118,4133],{"__ignoreMap":342},[346,4091,4092],{"class":348,"line":349},[346,4093,4094],{"class":529},"# Default selection: relu\n",[346,4096,4097,4100,4102,4104,4106,4108,4110,4112,4114,4116],{"class":348,"line":360},[346,4098,4099],{"class":356},"cfg_relu ",[346,4101,960],{"class":491},[346,4103,380],{"class":356},[346,4105,384],{"class":383},[346,4107,3885],{"class":623},[346,4109,603],{"class":383},[346,4111,1761],{"class":487},[346,4113,603],{"class":383},[346,4115,3848],{"class":623},[346,4117,632],{"class":383},[346,4119,4120,4122,4124,4126,4129,4131],{"class":348,"line":367},[346,4121,600],{"class":599},[346,4123,603],{"class":383},[346,4125,607],{"class":606},[346,4127,4128],{"class":610},"=== relu (default) ===",[346,4130,607],{"class":606},[346,4132,766],{"class":383},[346,4134,4135,4137,4139,4141,4143,4145,4147,4150,4152,4154],{"class":348,"line":375},[346,4136,600],{"class":599},[346,4138,603],{"class":383},[346,4140,1161],{"class":623},[346,4142,384],{"class":383},[346,4144,1166],{"class":623},[346,4146,603],{"class":383},[346,4148,4149],{"class":623},"cfg_relu",[346,4151,384],{"class":383},[346,4153,629],{"class":387},[346,4155,632],{"class":383},[784,4157],{"data":4158,"kind":787},"PT09IHJlbHUgKGRlZmF1bHQpID09PQp7X2NvbnZlcnRfOiBhbGwsIF9sYWNvXzogMSwgX3RhcmdldF86IHRvcmNoLm5uLlJlTFV9Cgo=",[337,4160,4162],{"className":339,"code":4161,"language":341,"meta":342,"style":342},"# Switch the activation to gelu. The model body is untouched — overriding the\n# composed group node's target propagates through every L.chosen(ActivationGroup)\n# reference at once. (We also bump dim_in to show scalar overrides compose too.)\ncfg_gelu = laco.load(\n    str(_mlp_path),\n    \"schema.dim_in=64\",\n    \"activation._target_=torch.nn.GELU\",   # swap the selected activation entry\n)\nprint(\"=== gelu (override) ===\")\nprint(laco.dump(cfg_gelu.activation))\n\n",[224,4163,4164,4169,4174,4179,4194,4205,4217,4231,4235,4250],{"__ignoreMap":342},[346,4165,4166],{"class":348,"line":349},[346,4167,4168],{"class":529},"# Switch the activation to gelu. The model body is untouched — overriding the\n",[346,4170,4171],{"class":348,"line":360},[346,4172,4173],{"class":529},"# composed group node's target propagates through every L.chosen(ActivationGroup)\n",[346,4175,4176],{"class":348,"line":367},[346,4177,4178],{"class":529},"# reference at once. (We also bump dim_in to show scalar overrides compose too.)\n",[346,4180,4181,4184,4186,4188,4190,4192],{"class":348,"line":375},[346,4182,4183],{"class":356},"cfg_gelu ",[346,4185,960],{"class":491},[346,4187,380],{"class":356},[346,4189,384],{"class":383},[346,4191,3885],{"class":623},[346,4193,1902],{"class":383},[346,4195,4196,4199,4201,4203],{"class":348,"line":396},[346,4197,4198],{"class":487},"    str",[346,4200,603],{"class":383},[346,4202,3848],{"class":623},[346,4204,2968],{"class":383},[346,4206,4207,4210,4213,4215],{"class":348,"line":410},[346,4208,4209],{"class":606},"    \"",[346,4211,4212],{"class":610},"schema.dim_in=64",[346,4214,607],{"class":606},[346,4216,2900],{"class":383},[346,4218,4219,4221,4224,4226,4228],{"class":348,"line":533},[346,4220,4209],{"class":606},[346,4222,4223],{"class":610},"activation._target_=torch.nn.GELU",[346,4225,607],{"class":606},[346,4227,423],{"class":383},[346,4229,4230],{"class":529},"   # swap the selected activation entry\n",[346,4232,4233],{"class":348,"line":539},[346,4234,766],{"class":383},[346,4236,4237,4239,4241,4243,4246,4248],{"class":348,"line":545},[346,4238,600],{"class":599},[346,4240,603],{"class":383},[346,4242,607],{"class":606},[346,4244,4245],{"class":610},"=== gelu (override) ===",[346,4247,607],{"class":606},[346,4249,766],{"class":383},[346,4251,4252,4254,4256,4258,4260,4262,4264,4267,4269,4271],{"class":348,"line":551},[346,4253,600],{"class":599},[346,4255,603],{"class":383},[346,4257,1161],{"class":623},[346,4259,384],{"class":383},[346,4261,1166],{"class":623},[346,4263,603],{"class":383},[346,4265,4266],{"class":623},"cfg_gelu",[346,4268,384],{"class":383},[346,4270,629],{"class":387},[346,4272,632],{"class":383},[784,4274],{"data":4275,"kind":787},"PT09IGdlbHUgKG92ZXJyaWRlKSA9PT0Ke19jb252ZXJ0XzogYWxsLCBfbGFjb186IDEsIF90YXJnZXRfOiB0b3JjaC5ubi5HRUxVfQoK",[216,4277,4278,4279,4282,4283,4286,4287,4290,4291,4293,4294,4296,4297,4299],{},"Notice that the ",[224,4280,4281],{},"_target_"," in the composed nodes changes from ",[224,4284,4285],{},"torch.nn.modules.activation.ReLU","\nto ",[224,4288,4289],{},"torch.nn.modules.activation.GELU"," everywhere ",[224,4292,2284],{}," appears,\nincluding both the ",[224,4295,2895],{}," layer and every ",[224,4298,3037],{}," layer. A single override propagates\nconsistently through the entire model graph.",[337,4301,4303],{"className":339,"code":4302,"language":341,"meta":342,"style":342},"# Instantiate both and verify the activation types\nmodel_relu = laco.instantiate(laco.load(str(_mlp_path)).model)\nmodel_gelu = laco.instantiate(\n    laco.load(str(_mlp_path), \"activation._target_=torch.nn.GELU\").model\n)\n\ndef first_activation(sequential):\n    \"\"\"Return the activation module in the input block.\"\"\"\n    return type(list(sequential.input.children())[1]).__name__\n\nprint(\"relu model — input activation:\", first_activation(model_relu))\nprint(\"gelu model — input activation:\", first_activation(model_gelu))\n\n",[224,4304,4305,4310,4346,4361,4391,4395,4399,4415,4424,4461,4465,4489],{"__ignoreMap":342},[346,4306,4307],{"class":348,"line":349},[346,4308,4309],{"class":529},"# Instantiate both and verify the activation types\n",[346,4311,4312,4315,4317,4319,4321,4323,4325,4327,4329,4331,4333,4335,4337,4339,4342,4344],{"class":348,"line":360},[346,4313,4314],{"class":356},"model_relu ",[346,4316,960],{"class":491},[346,4318,380],{"class":356},[346,4320,384],{"class":383},[346,4322,4055],{"class":623},[346,4324,603],{"class":383},[346,4326,1161],{"class":623},[346,4328,384],{"class":383},[346,4330,3885],{"class":623},[346,4332,603],{"class":383},[346,4334,1761],{"class":487},[346,4336,603],{"class":383},[346,4338,3848],{"class":623},[346,4340,4341],{"class":383},")).",[346,4343,3397],{"class":387},[346,4345,766],{"class":383},[346,4347,4348,4351,4353,4355,4357,4359],{"class":348,"line":367},[346,4349,4350],{"class":356},"model_gelu ",[346,4352,960],{"class":491},[346,4354,380],{"class":356},[346,4356,384],{"class":383},[346,4358,4055],{"class":623},[346,4360,1902],{"class":383},[346,4362,4363,4366,4368,4370,4372,4374,4376,4378,4380,4382,4384,4386,4388],{"class":348,"line":375},[346,4364,4365],{"class":623},"    laco",[346,4367,384],{"class":383},[346,4369,3885],{"class":623},[346,4371,603],{"class":383},[346,4373,1761],{"class":487},[346,4375,603],{"class":383},[346,4377,3848],{"class":623},[346,4379,1945],{"class":383},[346,4381,3836],{"class":606},[346,4383,4223],{"class":610},[346,4385,607],{"class":606},[346,4387,239],{"class":383},[346,4389,4390],{"class":387},"model\n",[346,4392,4393],{"class":348,"line":396},[346,4394,766],{"class":383},[346,4396,4397],{"class":348,"line":410},[346,4398,364],{"emptyLinePlaceholder":363},[346,4400,4401,4404,4407,4409,4413],{"class":348,"line":533},[346,4402,4403],{"class":468},"def",[346,4405,4406],{"class":457}," first_activation",[346,4408,603],{"class":383},[346,4410,4412],{"class":4411},"sFwrP","sequential",[346,4414,1659],{"class":383},[346,4416,4417,4419,4422],{"class":348,"line":539},[346,4418,941],{"class":940},[346,4420,4421],{"class":944},"Return the activation module in the input block.",[346,4423,948],{"class":940},[346,4425,4426,4429,4431,4433,4436,4438,4440,4442,4444,4446,4449,4452,4455,4458],{"class":348,"line":545},[346,4427,4428],{"class":352},"    return",[346,4430,559],{"class":487},[346,4432,603],{"class":383},[346,4434,4435],{"class":487},"list",[346,4437,603],{"class":383},[346,4439,4412],{"class":623},[346,4441,384],{"class":383},[346,4443,2895],{"class":387},[346,4445,384],{"class":383},[346,4447,4448],{"class":623},"children",[346,4450,4451],{"class":383},"())[",[346,4453,4454],{"class":495},"1",[346,4456,4457],{"class":383},"]).",[346,4459,4460],{"class":717},"__name__\n",[346,4462,4463],{"class":348,"line":551},[346,4464,364],{"emptyLinePlaceholder":363},[346,4466,4467,4469,4471,4473,4476,4478,4480,4482,4484,4487],{"class":348,"line":585},[346,4468,600],{"class":599},[346,4470,603],{"class":383},[346,4472,607],{"class":606},[346,4474,4475],{"class":610},"relu model — input activation:",[346,4477,607],{"class":606},[346,4479,423],{"class":383},[346,4481,4406],{"class":623},[346,4483,603],{"class":383},[346,4485,4486],{"class":623},"model_relu",[346,4488,632],{"class":383},[346,4490,4491,4493,4495,4497,4500,4502,4504,4506,4508,4511],{"class":348,"line":590},[346,4492,600],{"class":599},[346,4494,603],{"class":383},[346,4496,607],{"class":606},[346,4498,4499],{"class":610},"gelu model — input activation:",[346,4501,607],{"class":606},[346,4503,423],{"class":383},[346,4505,4406],{"class":623},[346,4507,603],{"class":383},[346,4509,4510],{"class":623},"model_gelu",[346,4512,632],{"class":383},[784,4514],{"data":4515,"kind":787},"cmVsdSBtb2RlbCDigJQgaW5wdXQgYWN0aXZhdGlvbjogUmVMVQpnZWx1IG1vZGVsIOKAlCBpbnB1dCBhY3RpdmF0aW9uOiBHRUxVCg==",[428,4517],{},[431,4519,4521],{"id":4520},"section-8-group-slot-bind-relationships","Section 8: Group \u002F Slot \u002F Bind Relationships",[216,4523,4524],{},"The table below shows how the four primitives relate at config-authoring time and at\nHydra-compose time.",[795,4526,4527,4540],{},[798,4528,4529],{},[801,4530,4531,4534,4537],{},[804,4532,4533],{},"Step",[804,4535,4536],{},"Primitive",[804,4538,4539],{},"Produces",[811,4541,4542,4568,4585,4600],{},[801,4543,4544,4546,4560],{},[816,4545,4454],{},[816,4547,4548,4551,4552,235,4554,235,4556,4559],{},[224,4549,4550],{},"ActivationGroup(L.Group[nn.Module])"," with ",[224,4553,1124],{},[224,4555,1216],{},[224,4557,4558],{},"silu"," entries",[816,4561,4562,4563,4565,4566],{},"Each entry registered in Hydra's ",[224,4564,1054],{}," under group ",[224,4567,1772],{},[801,4569,4570,4573,4578],{},[816,4571,4572],{},"2",[816,4574,4575],{},[224,4576,4577],{},"L.bind(MLPSchema.activation, ActivationGroup.relu)",[816,4579,4580,4581,1085,4583],{},"Validates the entry's group matches the slot, then a ",[224,4582,2043],{},[224,4584,2050],{},[801,4586,4587,4590,4595],{},[816,4588,4589],{},"3",[816,4591,4592],{},[224,4593,4594],{},"MLPSchema.activation: nn.Module = L.slot(ActivationGroup)",[816,4596,4597,4598],{},"Field default rewritten to ",[224,4599,1765],{},[801,4601,4602,4605,4610],{},[816,4603,4604],{},"4",[816,4606,4607,4609],{},[224,4608,2284],{}," in the model body",[816,4611,4612,4613,4615],{},"Same ",[224,4614,1765],{}," interpolation, resolved at instantiation time",[216,4617,4618,4619,4621],{},"At compose time, the defaults-list binding (step 2) fills the schema's slot\n(step 3), and every ",[224,4620,2284],{}," reference in the model body\n(step 4) resolves to that same selected entry.",[428,4623],{},[431,4625,4627,4628,4630,4631,4634],{"id":4626},"section-9-lparams-vs-lgroup-side-by-side","Section 9: ",[224,4629,261],{}," vs ",[224,4632,4633],{},"L.Group"," Side-by-Side",[216,4636,4637],{},"Both approaches can describe configurable components. The table below summarizes the\ntrade-offs so you can choose the right tool for each use case.",[337,4639,4641],{"className":339,"code":4640,"language":341,"meta":342,"style":342},"# ============================================================\n#  @L.params approach                  L.Group approach\n# ============================================================\n\n# --- @L.params ---                    # --- L.Group ---\n@L.params                               # class ActivationGroup(L.Group[nn.Module]):\nclass hps_params:                       #     relu = L.call(nn.ReLU)()\n    activation = nn.ReLU                #     gelu = L.call(nn.GELU)()\n                                        #     silu = L.call(nn.SiLU)()\n                                        #\n# Override via CLI:                     # Override via CLI:\n#   activation=nn.GELU                  #   +activationgroup=gelu\n#   (a free-form string — no           #   (validated at config-authoring\n#    validation until runtime)          #    time; typos are static errors)\n\nprint(\"@L.params: activation default type:\",\n      type(hps_params.activation).__name__)\nprint(\"L.Group: ActivationGroup entries:\",\n      [e.name for e in ActivationGroup.entries()])\n",[224,4642,4643,4648,4653,4657,4661,4666,4680,4692,4708,4713,4718,4723,4728,4733,4738,4742,4757,4777,4792],{"__ignoreMap":342},[346,4644,4645],{"class":348,"line":349},[346,4646,4647],{"class":529},"# ============================================================\n",[346,4649,4650],{"class":348,"line":360},[346,4651,4652],{"class":529},"#  @L.params approach                  L.Group approach\n",[346,4654,4655],{"class":348,"line":367},[346,4656,4647],{"class":529},[346,4658,4659],{"class":348,"line":375},[346,4660,364],{"emptyLinePlaceholder":363},[346,4662,4663],{"class":348,"line":396},[346,4664,4665],{"class":529},"# --- @L.params ---                    # --- L.Group ---\n",[346,4667,4668,4670,4672,4674,4677],{"class":348,"line":410},[346,4669,454],{"class":453},[346,4671,458],{"class":457},[346,4673,384],{"class":453},[346,4675,4676],{"class":457},"params",[346,4678,4679],{"class":529},"                               # class ActivationGroup(L.Group[nn.Module]):\n",[346,4681,4682,4684,4687,4689],{"class":348,"line":533},[346,4683,469],{"class":468},[346,4685,4686],{"class":472}," hps_params",[346,4688,484],{"class":383},[346,4690,4691],{"class":529},"                       #     relu = L.call(nn.ReLU)()\n",[346,4693,4694,4697,4699,4701,4703,4705],{"class":348,"line":539},[346,4695,4696],{"class":356},"    activation ",[346,4698,960],{"class":491},[346,4700,420],{"class":356},[346,4702,384],{"class":383},[346,4704,977],{"class":387},[346,4706,4707],{"class":529},"                #     gelu = L.call(nn.GELU)()\n",[346,4709,4710],{"class":348,"line":545},[346,4711,4712],{"class":529},"                                        #     silu = L.call(nn.SiLU)()\n",[346,4714,4715],{"class":348,"line":551},[346,4716,4717],{"class":529},"                                        #\n",[346,4719,4720],{"class":348,"line":585},[346,4721,4722],{"class":529},"# Override via CLI:                     # Override via CLI:\n",[346,4724,4725],{"class":348,"line":590},[346,4726,4727],{"class":529},"#   activation=nn.GELU                  #   +activationgroup=gelu\n",[346,4729,4730],{"class":348,"line":596},[346,4731,4732],{"class":529},"#   (a free-form string — no           #   (validated at config-authoring\n",[346,4734,4735],{"class":348,"line":635},[346,4736,4737],{"class":529},"#    validation until runtime)          #    time; typos are static errors)\n",[346,4739,4740],{"class":348,"line":640},[346,4741,364],{"emptyLinePlaceholder":363},[346,4743,4744,4746,4748,4750,4753,4755],{"class":348,"line":646},[346,4745,600],{"class":599},[346,4747,603],{"class":383},[346,4749,607],{"class":606},[346,4751,4752],{"class":610},"@L.params: activation default type:",[346,4754,607],{"class":606},[346,4756,2900],{"class":383},[346,4758,4759,4762,4764,4767,4769,4771,4773,4775],{"class":348,"line":654},[346,4760,4761],{"class":487},"      type",[346,4763,603],{"class":383},[346,4765,4766],{"class":623},"hps_params",[346,4768,384],{"class":383},[346,4770,629],{"class":387},[346,4772,239],{"class":383},[346,4774,718],{"class":717},[346,4776,766],{"class":383},[346,4778,4779,4781,4783,4785,4788,4790],{"class":348,"line":675},[346,4780,600],{"class":599},[346,4782,603],{"class":383},[346,4784,607],{"class":606},[346,4786,4787],{"class":610},"L.Group: ActivationGroup entries:",[346,4789,607],{"class":606},[346,4791,2900],{"class":383},[346,4793,4794,4797,4799,4801,4803,4806,4809,4811,4813,4815,4817],{"class":348,"line":691},[346,4795,4796],{"class":383},"      [",[346,4798,712],{"class":623},[346,4800,384],{"class":383},[346,4802,1290],{"class":387},[346,4804,4805],{"class":352}," for",[346,4807,4808],{"class":623}," e ",[346,4810,1242],{"class":352},[346,4812,915],{"class":623},[346,4814,384],{"class":383},[346,4816,1249],{"class":623},[346,4818,4819],{"class":383},"()])\n",[784,4821],{"data":4822,"kind":787},"QEwucGFyYW1zOiBhY3RpdmF0aW9uIGRlZmF1bHQgdHlwZTogc3RyCkwuR3JvdXA6IEFjdGl2YXRpb25Hcm91cCBlbnRyaWVzOiBbJ3JlbHUnLCAnZ2VsdScsICdzaWx1J10K",[795,4824,4825,4840],{},[798,4826,4827],{},[801,4828,4829,4832,4836],{},[804,4830,4831],{},"Property",[804,4833,4834],{},[224,4835,261],{},[804,4837,4838],{},[224,4839,300],{},[811,4841,4842,4853,4864,4875,4889,4903,4913],{},[801,4843,4844,4847,4850],{},[816,4845,4846],{},"Validated choice set",[816,4848,4849],{},"No — any string accepted",[816,4851,4852],{},"Yes — class attrs only",[801,4854,4855,4858,4861],{},[816,4856,4857],{},"Static type errors",[816,4859,4860],{},"No — runtime crash on typo",[816,4862,4863],{},"Yes — pyright catches typos",[801,4865,4866,4869,4872],{},[816,4867,4868],{},"IDE autocomplete",[816,4870,4871],{},"Partial — scalars only",[816,4873,4874],{},"Yes — entry attributes",[801,4876,4877,4880,4883],{},[816,4878,4879],{},"Nested object nodes",[816,4881,4882],{},"No — scalar values only",[816,4884,4885,4886,4888],{},"Yes — full ",[224,4887,1046],{}," nodes",[801,4890,4891,4894,4897],{},[816,4892,4893],{},"Registered in ConfigStore",[816,4895,4896],{},"No",[816,4898,4899,4900],{},"Yes — ",[224,4901,4902],{},"ConfigStore.store()",[801,4904,4905,4908,4910],{},[816,4906,4907],{},"Hydra group composition",[816,4909,4896],{},[816,4911,4912],{},"Yes — via defaults list",[801,4914,4915,4918,4927],{},[816,4916,4917],{},"Best for",[816,4919,4920,4921,235,4923,4926],{},"Scalar hyperparameters (",[224,4922,2130],{},[224,4924,4925],{},"bs",", …)",[816,4928,4929],{},"Swappable components (model, optim, …)",[428,4931],{},[431,4933,4935,4936,4939],{"id":4934},"section-10-bonus-lrequiredt-in-schemas","Section 10: Bonus, ",[224,4937,4938],{},"L.required[T]()"," in Schemas",[216,4941,4942,4943,4945,4946,4949,4950,4953],{},"Sometimes a schema field has no sensible default: it must be explicitly provided by\nevery caller. ",[224,4944,4938],{}," marks such fields at the schema level, producing\n",[224,4947,4948],{},"OmegaConf.MISSING"," as the default value. Attempting to load a config without\nsupplying the required field raises a ",[224,4951,4952],{},"MissingMandatoryValue"," error at compose time.",[216,4955,4956,4957,484],{},"The text-classifier example uses this for ",[224,4958,4959],{},"vocab_size",[337,4961,4963],{"className":339,"code":4962,"language":341,"meta":342,"style":342},"@L.config\nclass TextClassifierSchema:\n    \"\"\"vocab_size is required — no default.\"\"\"\n\n    vocab_size:   int       = L.required[int]()\n    embed_dim:    int       = 64\n    num_classes:  int       = 2\n    padding_idx:  int | None = 0\n\n# The field is MISSING at the dataclass level\nimport dataclasses\nfrom omegaconf import MISSING\nvocab_field = dataclasses.fields(TextClassifierSchema)[0]\nprint(f\"vocab_size default: {vocab_field.default!r}\")\nprint(f\"Is MISSING: {vocab_field.default is MISSING}\")\n",[224,4964,4965,4975,4984,4993,4997,5024,5037,5052,5072,5076,5081,5087,5098,5124,5152],{"__ignoreMap":342},[346,4966,4967,4969,4971,4973],{"class":348,"line":349},[346,4968,454],{"class":453},[346,4970,458],{"class":457},[346,4972,384],{"class":453},[346,4974,1453],{"class":457},[346,4976,4977,4979,4982],{"class":348,"line":360},[346,4978,469],{"class":468},[346,4980,4981],{"class":472}," TextClassifierSchema",[346,4983,476],{"class":383},[346,4985,4986,4988,4991],{"class":348,"line":367},[346,4987,941],{"class":940},[346,4989,4990],{"class":944},"vocab_size is required — no default.",[346,4992,948],{"class":940},[346,4994,4995],{"class":348,"line":375},[346,4996,364],{"emptyLinePlaceholder":363},[346,4998,4999,5002,5004,5007,5009,5011,5013,5016,5018,5021],{"class":348,"line":396},[346,5000,5001],{"class":356},"    vocab_size",[346,5003,484],{"class":383},[346,5005,5006],{"class":487},"   int",[346,5008,1487],{"class":491},[346,5010,963],{"class":356},[346,5012,384],{"class":383},[346,5014,5015],{"class":387},"required",[346,5017,562],{"class":383},[346,5019,5020],{"class":487},"int",[346,5022,5023],{"class":383},"]()\n",[346,5025,5026,5029,5031,5033,5035],{"class":348,"line":410},[346,5027,5028],{"class":356},"    embed_dim",[346,5030,484],{"class":383},[346,5032,1498],{"class":487},[346,5034,1487],{"class":491},[346,5036,524],{"class":495},[346,5038,5039,5042,5044,5047,5049],{"class":348,"line":533},[346,5040,5041],{"class":356},"    num_classes",[346,5043,484],{"class":383},[346,5045,5046],{"class":487},"  int",[346,5048,1487],{"class":491},[346,5050,5051],{"class":495}," 2\n",[346,5053,5054,5057,5059,5061,5064,5067,5069],{"class":348,"line":539},[346,5055,5056],{"class":356},"    padding_idx",[346,5058,484],{"class":383},[346,5060,5046],{"class":487},[346,5062,5063],{"class":491}," |",[346,5065,5066],{"class":2867}," None",[346,5068,492],{"class":491},[346,5070,5071],{"class":495}," 0\n",[346,5073,5074],{"class":348,"line":545},[346,5075,364],{"emptyLinePlaceholder":363},[346,5077,5078],{"class":348,"line":551},[346,5079,5080],{"class":529},"# The field is MISSING at the dataclass level\n",[346,5082,5083,5085],{"class":348,"line":585},[346,5084,353],{"class":352},[346,5086,357],{"class":356},[346,5088,5089,5091,5093,5095],{"class":348,"line":590},[346,5090,399],{"class":352},[346,5092,402],{"class":356},[346,5094,353],{"class":352},[346,5096,5097],{"class":717}," MISSING\n",[346,5099,5100,5103,5105,5107,5109,5111,5113,5116,5119,5121],{"class":348,"line":596},[346,5101,5102],{"class":356},"vocab_field ",[346,5104,960],{"class":491},[346,5106,1603],{"class":356},[346,5108,384],{"class":383},[346,5110,1652],{"class":623},[346,5112,603],{"class":383},[346,5114,5115],{"class":623},"TextClassifierSchema",[346,5117,5118],{"class":383},")[",[346,5120,743],{"class":495},[346,5122,5123],{"class":383},"]\n",[346,5125,5126,5128,5130,5132,5135,5137,5140,5142,5144,5146,5148,5150],{"class":348,"line":635},[346,5127,600],{"class":599},[346,5129,603],{"class":383},[346,5131,699],{"class":468},[346,5133,5134],{"class":610},"\"vocab_size default: ",[346,5136,704],{"class":495},[346,5138,5139],{"class":623},"vocab_field",[346,5141,384],{"class":383},[346,5143,1704],{"class":387},[346,5145,1276],{"class":468},[346,5147,721],{"class":495},[346,5149,607],{"class":610},[346,5151,766],{"class":383},[346,5153,5154,5156,5158,5160,5163,5165,5167,5169,5171,5174,5177,5179,5181],{"class":348,"line":640},[346,5155,600],{"class":599},[346,5157,603],{"class":383},[346,5159,699],{"class":468},[346,5161,5162],{"class":610},"\"Is MISSING: ",[346,5164,704],{"class":495},[346,5166,5139],{"class":623},[346,5168,384],{"class":383},[346,5170,1704],{"class":387},[346,5172,5173],{"class":491}," is",[346,5175,5176],{"class":599}," MISSING",[346,5178,721],{"class":495},[346,5180,607],{"class":610},[346,5182,766],{"class":383},[784,5184],{"data":5185,"kind":787},"dm9jYWJfc2l6ZSBkZWZhdWx0OiAnPz8\u002FJwpJcyBNSVNTSU5HOiBUcnVlCg==",[337,5187,5189],{"className":339,"code":5188,"language":341,"meta":342,"style":342},"# Loading without providing vocab_size raises a clear error at compose time\nfrom omegaconf import MissingMandatoryValue\n\ntry:\n    # This will raise because vocab_size has no default\n    cfg_missing = laco.load(\"configs:\u002F\u002Fexamples\u002Ftyped\u002Ftext_classifier.py#schema\")\n    # Accessing the missing field triggers the error\n    _ = cfg_missing.vocab_size\nexcept MissingMandatoryValue as e:\n    print(f\"MissingMandatoryValue: {e}\")\n",[224,5190,5191,5196,5207,5211,5217,5222,5246,5251,5265,5279],{"__ignoreMap":342},[346,5192,5193],{"class":348,"line":349},[346,5194,5195],{"class":529},"# Loading without providing vocab_size raises a clear error at compose time\n",[346,5197,5198,5200,5202,5204],{"class":348,"line":360},[346,5199,399],{"class":352},[346,5201,402],{"class":356},[346,5203,353],{"class":352},[346,5205,5206],{"class":356}," MissingMandatoryValue\n",[346,5208,5209],{"class":348,"line":367},[346,5210,364],{"emptyLinePlaceholder":363},[346,5212,5213,5215],{"class":348,"line":375},[346,5214,649],{"class":352},[346,5216,476],{"class":383},[346,5218,5219],{"class":348,"line":396},[346,5220,5221],{"class":529},"    # This will raise because vocab_size has no default\n",[346,5223,5224,5227,5229,5231,5233,5235,5237,5239,5242,5244],{"class":348,"line":410},[346,5225,5226],{"class":356},"    cfg_missing ",[346,5228,960],{"class":491},[346,5230,380],{"class":356},[346,5232,384],{"class":383},[346,5234,3885],{"class":623},[346,5236,603],{"class":383},[346,5238,607],{"class":606},[346,5240,5241],{"class":610},"configs:\u002F\u002Fexamples\u002Ftyped\u002Ftext_classifier.py#schema",[346,5243,607],{"class":606},[346,5245,766],{"class":383},[346,5247,5248],{"class":348,"line":533},[346,5249,5250],{"class":529},"    # Accessing the missing field triggers the error\n",[346,5252,5253,5255,5257,5260,5262],{"class":348,"line":539},[346,5254,1354],{"class":356},[346,5256,960],{"class":491},[346,5258,5259],{"class":356}," cfg_missing",[346,5261,384],{"class":383},[346,5263,5264],{"class":387},"vocab_size\n",[346,5266,5267,5269,5272,5275,5277],{"class":348,"line":545},[346,5268,678],{"class":352},[346,5270,5271],{"class":356}," MissingMandatoryValue ",[346,5273,5274],{"class":352},"as",[346,5276,686],{"class":356},[346,5278,476],{"class":383},[346,5280,5281,5283,5285,5287,5290,5292,5294,5296,5298],{"class":348,"line":551},[346,5282,694],{"class":599},[346,5284,603],{"class":383},[346,5286,699],{"class":468},[346,5288,5289],{"class":610},"\"MissingMandatoryValue: ",[346,5291,704],{"class":495},[346,5293,712],{"class":623},[346,5295,721],{"class":495},[346,5297,607],{"class":610},[346,5299,766],{"class":383},[784,5301],{"data":5302,"kind":787},"TWlzc2luZ01hbmRhdG9yeVZhbHVlOiBNaXNzaW5nIG1hbmRhdG9yeSB2YWx1ZTogc2NoZW1hLnZvY2FiX3NpemUKICAgIGZ1bGxfa2V5OiBzY2hlbWEudm9jYWJfc2l6ZQogICAgb2JqZWN0X3R5cGU9VGV4dENsYXNzaWZpZXJTY2hlbWEK",[337,5304,5306],{"className":339,"code":5305,"language":341,"meta":342,"style":342},"# Providing the value via an override resolves it cleanly\ncfg_ok = laco.load(\n    \"configs:\u002F\u002Fexamples\u002Ftyped\u002Ftext_classifier.py?schema.vocab_size=1000#schema\"\n)\nprint(f\"vocab_size: {cfg_ok.vocab_size}\")\nprint(f\"embed_dim:  {cfg_ok.embed_dim}\")\n",[224,5307,5308,5313,5328,5337,5341,5367],{"__ignoreMap":342},[346,5309,5310],{"class":348,"line":349},[346,5311,5312],{"class":529},"# Providing the value via an override resolves it cleanly\n",[346,5314,5315,5318,5320,5322,5324,5326],{"class":348,"line":360},[346,5316,5317],{"class":356},"cfg_ok ",[346,5319,960],{"class":491},[346,5321,380],{"class":356},[346,5323,384],{"class":383},[346,5325,3885],{"class":623},[346,5327,1902],{"class":383},[346,5329,5330,5332,5335],{"class":348,"line":367},[346,5331,4209],{"class":606},[346,5333,5334],{"class":610},"configs:\u002F\u002Fexamples\u002Ftyped\u002Ftext_classifier.py?schema.vocab_size=1000#schema",[346,5336,3842],{"class":606},[346,5338,5339],{"class":348,"line":375},[346,5340,766],{"class":383},[346,5342,5343,5345,5347,5349,5352,5354,5357,5359,5361,5363,5365],{"class":348,"line":396},[346,5344,600],{"class":599},[346,5346,603],{"class":383},[346,5348,699],{"class":468},[346,5350,5351],{"class":610},"\"vocab_size: ",[346,5353,704],{"class":495},[346,5355,5356],{"class":623},"cfg_ok",[346,5358,384],{"class":383},[346,5360,4959],{"class":387},[346,5362,721],{"class":495},[346,5364,607],{"class":610},[346,5366,766],{"class":383},[346,5368,5369,5371,5373,5375,5378,5380,5382,5384,5387,5389,5391],{"class":348,"line":410},[346,5370,600],{"class":599},[346,5372,603],{"class":383},[346,5374,699],{"class":468},[346,5376,5377],{"class":610},"\"embed_dim:  ",[346,5379,704],{"class":495},[346,5381,5356],{"class":623},[346,5383,384],{"class":383},[346,5385,5386],{"class":387},"embed_dim",[346,5388,721],{"class":495},[346,5390,607],{"class":610},[346,5392,766],{"class":383},[784,5394],{"data":5395,"kind":787},"dm9jYWJfc2l6ZTogMTAwMAplbWJlZF9kaW06ICA2NAo=",[428,5397],{},[431,5399,5401],{"id":5400},"summary","Summary",[795,5403,5404,5413],{},[798,5405,5406],{},[801,5407,5408,5410],{},[804,5409,4536],{},[804,5411,5412],{},"What it does",[811,5414,5415,5425,5445,5462,5479,5489,5501],{},[801,5416,5417,5422],{},[816,5418,5419],{},[224,5420,5421],{},"class G(L.Group[T])",[816,5423,5424],{},"Declares a group of interchangeable config nodes; registers each attribute in Hydra's ConfigStore",[801,5426,5427,5431],{},[816,5428,5429],{},[224,5430,306],{},[816,5432,5433,5434,5437,5438,5440,5441,5444],{},"Turns a schema class into a real ",[224,5435,5436],{},"dataclass","; resolves ",[224,5439,312],{}," fields into ",[224,5442,5443],{},"${package}"," interpolations",[801,5446,5447,5452],{},[816,5448,5449],{},[224,5450,5451],{},"L.slot(G)",[816,5453,5454,5455,5458,5459],{},"Field specifier: links a schema field to group ",[224,5456,5457],{},"G","; default becomes ",[224,5460,5461],{},"\"${field_name}\"",[801,5463,5464,5469],{},[816,5465,5466],{},[224,5467,5468],{},"L.bind(slot, entry)",[816,5470,5471,5472,5474,5475,5478],{},"Produces a ",[224,5473,2043],{}," (",[224,5476,5477],{},"{group: name}","); validates group membership at authoring time",[801,5480,5481,5486],{},[816,5482,5483],{},[224,5484,5485],{},"L.Defaults(L.self_, L.bind(...))",[816,5487,5488],{},"Builds a Hydra defaults list that tells the composer which entry to use for each slot",[801,5490,5491,5496],{},[816,5492,5493],{},[224,5494,5495],{},"L.chosen(G)",[816,5497,5498,5499],{},"In-body interpolation that resolves to whichever entry was selected for group ",[224,5500,5457],{},[801,5502,5503,5507],{},[816,5504,5505],{},[224,5506,4938],{},[816,5508,5509,5510,5513],{},"Marks a schema field as having no default (",[224,5511,5512],{},"MISSING","); forces callers to supply a value",[216,5515,5516],{},[219,5517,5518,5519,4630,5521,484],{},"When to use ",[224,5520,261],{},[224,5522,300],{},[2368,5524,5525,5534],{},[290,5526,5527,5528,5530,5531,5533],{},"Use ",[224,5529,261],{}," for ",[219,5532,868],{},": learning rate, batch size, and epoch\ncount are values you tweak per run.",[290,5535,5527,5536,5530,5538,5540],{},[224,5537,300],{},[219,5539,265],{},": optimizer family, activation function,\nloss function, and encoder architecture are objects you swap wholesale.",[428,5542],{},[216,5544,5545,222,5548,5551,5552,5555,5556,5559],{},[219,5546,5547],{},"Next:",[224,5549,5550],{},"08.pipeline-configs.ipynb"," shows how to wire multiple typed components into a\nfull training bundle with ",[224,5553,5554],{},"L.Dict",", relative imports, and the ",[224,5557,5558],{},"@L.task"," entry point.",[5561,5562,5563],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stp6e, html code.shiki .stp6e{--shiki-light:#39ADB5;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s2W-s, html code.shiki .s2W-s{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#9ECBFF;--shiki-dark-font-style:inherit}html pre.shiki code .sithA, html code.shiki .sithA{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#9ECBFF;--shiki-dark-font-style:inherit}html pre.shiki code .swQdS, html code.shiki .swQdS{--shiki-light:#E53935;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sFwrP, html code.shiki .sFwrP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}",{"title":342,"searchDepth":367,"depth":367,"links":5565},[5566,5568,5572,5577,5582,5584,5586,5587,5588,5590,5592],{"id":433,"depth":360,"text":5567},"Section 1: The Limitation of @L.params for Swappable Components",{"id":885,"depth":360,"text":5569,"children":5570},"Section 2: L.Group[T], Declaring a Config Group",[5571],{"id":1305,"depth":367,"text":1306},{"id":1405,"depth":360,"text":5573,"children":5574},"Section 3: @L.config, The Typed Schema",[5575],{"id":1718,"depth":367,"text":5576},"How L.slot works",{"id":1866,"depth":360,"text":5578,"children":5579},"Section 4: L.Defaults, The Defaults List",[5580],{"id":1982,"depth":367,"text":5581},"Step-by-step breakdown of L.bind",{"id":2264,"depth":360,"text":5583},"Section 5: L.chosen, Referencing the Selected Entry in the Config Body",{"id":2401,"depth":360,"text":5585},"Section 6: Full Walkthrough, typed\u002Fmlp.py",{"id":4077,"depth":360,"text":4078},{"id":4520,"depth":360,"text":4521},{"id":4626,"depth":360,"text":5589},"Section 9: @L.params vs L.Group Side-by-Side",{"id":4934,"depth":360,"text":5591},"Section 10: Bonus, L.required[T]() in Schemas",{"id":5400,"depth":360,"text":5401},"Prerequisites: 01.why-laco.ipynb through 05.loading-saving-cli.ipynb. Familiarity with Python dataclasses (@dataclass, fields()).","md",{"notebook":363},{"icon":25},{"title":47,"description":5593},"fHDHIzmT7mYDHQoXXqiIj6l_Hcnj78zSZeCKjChtJRc",{},1785687302182]