<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 29, 2018 at 7:31 PM, ☂Josh Chia (謝任中) <span dir="ltr"><<a href="mailto:joshchia@gmail.com" target="_blank">joshchia@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Rahul's idea works within a package to prevent cascading builds of modules, but when the base package needs to be rebuilt, it is unregistered first as are its direct and indirect dependents, so unfortunately the idea works on an intra-package level but not an inter-package level.<div><br></div><div>Regarding Gleb's comment, isn't this CPP distinction between embedded and external file going to affect a lot of code including their function signatures? (One version takes a filename for the data file and does IO and another version doesn't) Sounds hard to maintain.</div></div></blockquote><div><br></div><div>Well, you can wrap your data in IO:<br><br></div><div>#ifdef DEVEL_BUILD<br></div><div>
constantData'
:: ByteString<br>constantData' = $(embedFile "blabla") <br><br></div><div>constantData :: IO ByteString<br></div><div>constantData = return
constantData
'<br></div><div>#else<br>
constantData :: IO ByteString
<br></div><div>constantData = readFile "blabla"<br></div><div>#endif<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="m_3588421984050880831h5"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 29, 2018 at 2:14 PM, Rahul Muttineni <span dir="ltr"><<a href="mailto:rahulmutt@gmail.com" target="_blank">rahulmutt@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="m_3588421984050880831m_691680029792990600m_-6483542358564621367h5"><div>Hi Josh,</div><div><br></div><div>I just tried a quick experiment with stack resolver lts-11.2 and I'd like to share the results as there are interesting:</div><div><br></div><div>1. Consider the following module setup that's a simplified version of your situation<br></div><div>Dependencies:</div><div>- Main depends on Hi <br></div><div>- Hi depends on Hum</div><div>- Hee depends on Hum</div><div><br></div><div>Main.hs:</div><div>```</div><div>module Main where<br><br>import Hi<br>import Hee<br><br>main :: IO ()<br>main = print $ hi ++ hee ++ "!"<br>```</div><div><br></div><div>Hee.hs:</div><div>```</div><div>module Hee (hee) where<br><br>import Hum (hum)<br><br>hee :: String<br>hee = "hee1" ++ hum<br>```</div><div><br></div><div>Hi.hs</div><div>```</div><div>module Hi (hi) where<br><br>import Hum (hum)<br><br>hi :: String<br>hi = "hi1" ++ hum<br></div><div>```</div><div><br></div><div>Hum.hs</div><div>```</div><div>module Hum (hum) where<br><br>hum :: String<br>hum = "hum"<br>```</div><div><br></div><div>2. Now build it once with `stack build`.</div><div>3. Now change "hum" to "hum1" and run `stack build` notice that all 4 modules will recompile.</div><div>4. Now add {-# NOINLINE hum #-} just above hum :: String and run `stack build`<br></div><div>5. Change hum again and run `stack build`.</div><div>6. Only Hum will recompile!</div><div><br></div><div>Lesson:
Add NOINLINE to any function/value that you change frequently and don't
want to trigger massive recompilations. This does come at a performace
tradeoff since GHC will not be able to inline whatever you added that
pragma to, but your compile-time will be saved. In your case of
hard-coded data, I think you won't be able to measure any performance
penalty.<br></div><div><br></div><div>Hope that helps,</div></div></div><div>Rahul<div class="m_3588421984050880831m_691680029792990600m_-6483542358564621367m_3017912124446510861gmail-yj6qo m_3588421984050880831m_691680029792990600m_-6483542358564621367m_3017912124446510861gmail-ajU"><div id="m_3588421984050880831m_691680029792990600m_-6483542358564621367m_3017912124446510861gmail-:42i" class="m_3588421984050880831m_691680029792990600m_-6483542358564621367m_3017912124446510861gmail-ajR"><img class="m_3588421984050880831m_691680029792990600m_-6483542358564621367m_3017912124446510861gmail-ajT" src="https://ssl.gstatic.com/ui/v1/icons/mail/images/cleardot.gif"></div></div></div><br></div><div class="gmail_extra"><br><div class="gmail_quote"><span>On Thu, Mar 29, 2018 at 10:39 AM, ☂Josh Chia (謝任中) <span dir="ltr"><<a href="mailto:joshchia@gmail.com" target="_blank">joshchia@gmail.com</a>></span> wrote:<br></span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="m_3588421984050880831m_691680029792990600m_-6483542358564621367h5"><div dir="ltr">Hi,<div><br></div><div>In my project, I have multiple packages. One of the packages, packageA, is very fundamental and depended on directly and indirectly by almost all the other packages. It has functions that use some hard-coded data (a ByteString top-level variable) also defined within packageA.</div><div><br></div><div>This hard-coded data is appended regularly, causing packageA to be rebuilt and thus almost all the other packages to be rebuilt, and building takes a painfully long time. I know I can move this hard-coded data to a file that's read at run-time, but that means one more item to plumb in at run-time (where to find the file), and IO (preventing the functions from being pure), so I would like to keep it hard-coded.</div><div><br></div><div>Is there an elegant way to prevent or minimize the cascading rebuild of the dependent packages just because the hard-coded data in packageA changed?</div><div><br></div><div>For analogy, in C or C++, source code gets compiled to .o files, one for each .cpp source file. Multiple .o files get linked into executables. So, unless the interface (.hpp files) also change, an implementation (.cpp file) change does not cause dependents to be recompiled to get new .o files, although dependent executables get relinked. I'm not familiar with the compilation and linking logic in GHC so maybe it has additional complications.</div><div><br></div><div>BTW, I'm using stack, in case it makes any difference to the nature of the problem.</div><span class="m_3588421984050880831m_691680029792990600m_-6483542358564621367m_3017912124446510861HOEnZb"><font color="#888888"><div><br></div><div>Josh</div></font></span></div>
<br></div></div><span>______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
Only members subscribed via the mailman list are allowed to post.<br></span></blockquote></div><span class="m_3588421984050880831m_691680029792990600m_-6483542358564621367HOEnZb"><font color="#888888"><br><br clear="all"><br>-- <br><div class="m_3588421984050880831m_691680029792990600m_-6483542358564621367m_3017912124446510861gmail_signature" data-smartmail="gmail_signature">Rahul Muttineni</div>
</font></span></div>
</blockquote></div><br></div></div></div></div>
<br>______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
Only members subscribed via the mailman list are allowed to post.<br></blockquote></div><br></div></div>